Query with JOIN slow - php

why my query take about 2 minutes to process?
i need to take attribute from 8 table.
how can i join those table and make it a fast query?
the reason why i want to join those table is bacause i want to fetchAll(PDO::FETCH_ASSOC) from user input progCode
this is my query :
"SELECT DISTINCT a.`ProgCode`, a.`Program`
FROM (select `i`.`name` AS `LC`,`f`.`name` AS `Intake`,`a`.`student_id`
AS `student_id`,`b`.`matricNo`
AS `matricNo`,`b`.`name`
AS `Nama`,`a`.`sem_id`
AS `sem_id`,`c`.`name`
AS `Sessi`,`e`.`code`
AS `ProgCode`,`e`.`name`
AS `Program`,`a`.`sub_id`
AS `sub_id`,`d`.`code`
AS `SubCode`,`d`.`name`
AS `Subject`,`a`.`grade`
AS `grade`,`h`.`credit`
AS `CurrentCreditHour`,`g`.`totalcredit`
AS `TotalCreditHour`,`g`.`gpa`
AS `GPA`,`g`.`cgpa`
AS `CGPA` from ((((((((`admin_sub_mark` `a` join `enrl_student` `b`)
join `struc_session` `c`)
join `struc_session` `f`)
join `struc_subject` `d`)
join `struc_program` `e`)
join `admin_sem_wise_cgpa` `g`)
join `admin_sem_wise_gpa` `h`)
join `struc_learningcentre` `i`)
where ((`b`.`id` = `a`.`student_id`)
and (`d`.`id` = `a`.`sub_id`)
and (`c`.`id` = `a`.`sem_id`)
and (`e`.`id` = `b`.`program_id`)
and (`f`.`id` = `b`.`intake_id`)
and (`i`.`id` = `b`.`learningCenter_id`)
and (`a`.`student_id` = `g`.`student_id`)
and (`a`.`sem_id` = `g`.`sem_id`)
and (`h`.`student_id` = `g`.`student_id`)
and (`h`.`sem_id` = `g`.`sem_id`)) order by `b`.`name`) a
ORDER BY `Program` ASC"
this is my explain query:
id| select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | g | ALL | NULL |NULL | NULL | NULL| 6049 | Using temporary;
Using filesort
1 | SIMPLE | h | ALL | NULL | NULL | NULL | NULL | 6055 | Using where |
1 | SIMPLE | c | eq_ref | PRIMARY | PRIMARY | 257 | educate_aeu2.g.sem_id 1
1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 257 | educate_aeu2.h.student_id 1 Using where
1 | SIMPLE | f | eq_ref |PRIMARY | PRIMARY | 257 | educate_aeu2.b.intake_id 1
1 | SIMPLE | e | eq_ref | PRIMARY | PRIMARY | 257 | educate_aeu2.b.program_id 1
1 | SIMPLE | i | eq_ref | PRIMARY | PRIMARY | 257 | educate_aeu2.b.learningCenter_id 1
1 | SIMPLE | a |ALL | NULL | NULL | NULL | NULL | 17077 | Using where
1 | SIMPLE | d | eq_ref | PRIMARY | PRIMARY | 257 | educate_aeu2.a.sub_id 1

You are retreiving a lot of fields in the inner select and doing a sort, then ignoring most of those fields and doing another sort. This will waste time
Quick clean up of the code gives:-
SELECT DISTINCT
e.code AS ProgCode,
e.name AS Program
FROM admin_sub_mark a
JOIN enrl_student b ON b.id = a.student_id
JOIN struc_session c ON c.id = a.sem_id
JOIN struc_session f ON f.id = b.intake_id
JOIN struc_subject d ON d.id = a.sub_id
JOIN struc_program e ON e.id = b.program_id
JOIN admin_sem_wise_cgpa g ON a.student_id = g.student_id AND a.sem_id = g.sem_id
JOIN admin_sem_wise_gpa h ON h.student_id = g.student_id AND h.sem_id = g.sem_id
JOIN struc_learningcentre i ON i.id = b.learningCenter_id
ORDER BY e.name ASC
Not sure whether you need to access all the tables.
Further what indexes do you have on the tables? If a query like this is running slowly then the culprit is normally the indexes but without knowing what they are (or better, the output from an EXPLAIN) we will struggle to provide any useful help

Related

This Mysql SQL Select query takes 33 mins to execute

Title says it all. Do you think anyone could help me untangle this? or if someone could point me out to what else could be causing it to take so much time. The query takes about half an hour to run. The guy who wrote this tried doing it in a loop, by removing the table from the last join statement and then querying the field.title for each vote. i was hoping to bring the result to about 5 mins.
some extra info:
The query result is 83,531 rows
The vote table size is 30 MB (261,169 rows)
SELECT `vote`.`id` `vote_id`, `branch`.`name` `branch`, `brand`.`name` `brand`, DATE(vote.created_at) `date`, HOUR(vote.created_at) `time_hour`,
MINUTE(vote.created_at) `time_minute`, `vote`.`is_like`, `voter`.`name`, `voter`.`telephone`, `voter`.`email`, popups_votes.title `popup_title`,
popups_votes.value `popup_value`, GROUP_CONCAT(dis.field SEPARATOR '|') `reasons`
FROM (`vote`)
LEFT JOIN `voter` ON `voter`.`id` = `vote`.`voter_id`
LEFT JOIN `device` ON `device`.`id` = `vote`.`device_id`
LEFT JOIN `branch` ON `branch`.`id` = `device`.`branch_id`
LEFT JOIN `brand` ON `brand`.`id` = `branch`.`brand_id`
LEFT JOIN `popups_votes` ON popups_votes.vote_id = vote.id
LEFT JOIN (SELECT vote_dislike.vote_id `vote_id`, field.title `field` FROM vote_dislike
LEFT JOIN branch_dislike_field ON branch_dislike_field.id = vote_dislike.branch_dislike_id
LEFT JOIN field ON field.id = branch_dislike_field.field_id) dis
ON dis.vote_id = vote.id
WHERE (vote.device_id in
(
Select d.id
From device d
WHERE d.branch_id IN (SELECT id FROM branch WHERE brand_id = 7)
)
)
AND (vote.created_at >= FROM_UNIXTIME('$from_time') AND vote.created_at <= FROM_UNIXTIME('$to_time') )
GROUP BY vote.id
EDIT: this is the explain {query} output:
+------+-------------+----------------------+--------+----------------------+-----------+---------+-------------------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------------------+--------+----------------------+-----------+---------+-------------------------------------------+------+----------------------------------------------+
| 1 | PRIMARY | branch | ref | PRIMARY,brand_id | brand_id | 4 | const | 20 | Using index; Using temporary; Using filesort |
| 1 | PRIMARY | d | ref | PRIMARY,branch_id | branch_id | 4 | river_back.branch.id | 1 | Using index |
| 1 | PRIMARY | vote | ref | device_id,created_at | device_id | 4 | river_back.d.id | 1200 | Using where |
| 1 | PRIMARY | voter | eq_ref | PRIMARY | PRIMARY | 4 | river_back.vote.voter_id | 1 | |
| 1 | PRIMARY | device | eq_ref | PRIMARY | PRIMARY | 4 | river_back.d.id | 1 | |
| 1 | PRIMARY | branch | eq_ref | PRIMARY | PRIMARY | 4 | river_back.device.branch_id | 1 | Using where |
| 1 | PRIMARY | brand | eq_ref | PRIMARY | PRIMARY | 4 | river_back.branch.brand_id | 1 | Using where |
| 1 | PRIMARY | popups_votes | ref | vote_id | vote_id | 5 | river_back.vote.id | 602 | |
| 1 | PRIMARY | vote_dislike | ref | vote_id | vote_id | 4 | river_back.vote.id | 1 | |
| 1 | PRIMARY | branch_dislike_field | eq_ref | PRIMARY | PRIMARY | 4 | river_back.vote_dislike.branch_dislike_id | 1 | Using where |
| 1 | PRIMARY | field | eq_ref | PRIMARY | PRIMARY | 4 | river_back.branch_dislike_field.field_id | 1 | Using where |
+------+-------------+----------------------+--------+----------------------+-----------+---------+-------------------------------------------+------+----------------------------------------------+
You should check that all the data you are selecting are indexed and you have foreign keys.
How do MySQL indexes work?
Basically an index on a table works like an index in a book (that's
where the name came from):
Let's say you have a book about databases and you want to find some
information about, say, storage. Without an index (assuming no other
aid, such as a table of contents) you'd have to go through the pages
one by one, until you found the topic (that's a full table scan). On
the other hand, an index has a list of keywords, so you'd consult the
index and see that storage is mentioned on pages 113-120,231 and 354.
Then you could flip to those pages directly, without searching (that's
a search with an index, somewhat faster).
Basics of Foreign Keys in MySQL?
FOREIGN KEYS just ensure your data are consistent.
They do not improve queries in sense of efficiency, they just make
some wrong queries fail.
Do not use LEFT unless you are expecting the "right" table to have missing rows.
In particular, the Optimizer probably cannot start with the 'derived table' since it is hiding to the right of a LEFT.
Do not use IN ( SELECT ... ); if possible change to EXISTS ( SELECT * ...) or JOIN.
Try to avoid the "inflate-deflate" caused by JOIN ... GROUP BY. If possible find the ids of interest without needing a GROUP BY, then JOIN to the other tables.
Putting many of those together, does this get you close to the desired result, at least in the sense of getting the correct vote.id values?
SELECT vote.id
FROM vote AS v
JOIN (
SELECT vote_dislike.vote_id `vote_id`, field.title `field`
FROM vote_dislike AS vd
LEFT JOIN branch_dislike_field AS bd
ON bd.id = vd.branch_dislike_id
LEFT JOIN field
ON field.id = bd.field_id
) AS dis ON dis.vote_id = v.id
JOIN device AS d ON v.device_id = d.id
JOIN branch AS b ON d.branch_id = b.id
WHERE b.brand_id = 7
AND v.created_at >= ...
AND v.created_at <= ...
Then:
SELECT lots of stuff
FROM ( the above query ) AS x
JOIN vote v ON x.id = v.id -- yes, dig back into `vote` for the other stuff
JOIN voter ...
JOIN ...
but with no GROUP BY.

mysql: combining columns from for tables

i have this 4 tables
table FRUIT, ID is Primary key
| ID | code | A | B |
--------------------------------------------
| 1 | a01 | apple1 | quava1 |
| 2 | a02 | apple2 | quava2 |
table FLOWER, ID is Primary key
| ID | code | C | D |
--------------------------------------------
| 1 | a01 | Rose1 | Plumer1 |
| 2 | a02 | Rose2 | Plumer2 |
table ANIMAL, ID is Primary key
| ID | code | E | F |
--------------------------------------------
| 1 | a01 | butterfly1 | cat1 |
| 2 | a02 | butterfly2 | cat2 |
table DAY, code is Primary key
| code | G |
-------------------------------------
| a01 | Monday |
| a02 | Tuesday|
i want to call and combined those 4 tables into like this
| ID | A | B | C | D | E | F | G |code |
--------------------------------------------------------------------------------
| 1 | apple1 | quava1 | Rose1 | Plumer1 |butterfly1 | cat1 |Monday |a01 |
| 2 | apple2 | quava2 | Rose2 | Plumer2 |butterfly2 | cat2 |Tuesday |a02 |
this is the code:
SELECT day*, fruit*, flower*, animal*
FROM day
LEFT JOIN fruit
ON day.code = fruit.code
LEFT JOIN flower
ON day.code = flower.code
LEFT JOIN flower
ON day.code = animal.code
ORDER BY day.code DESC;
it is said that column code is ambiguous. and cannot show the table.
i need help. how can i fix this?
I would do it in this manner, using Aliases and JOINs to join all the tables (including the animal table which you forgot), and of course not forgetting to include the periods . where needed:
SELECT fr.ID, fr.A, fr.B, fl.C, fl.D, a.E, a.F, d.G, fr.code
FROM `day` AS d
LEFT JOIN `fruit` AS fr ON d.code = fr.code
LEFT JOIN `flower` AS fl ON d.code = fl.code
LEFT JOIN `animal` AS a ON d.code = a.code
ORDER BY d.code ASC;
you forget to add . between column_name and * like day.*
Try This
SELECT `day`.*, fruit.*, flower.*, animal.*
FROM `day`
LEFT JOIN fruit
ON `day`.code = fruit.code
LEFT JOIN flower
ON `day`.code = flower.code
LEFT JOIN flower
ON `day`.code = animal.code
ORDER BY `day`.code DESC;
Beside the fact that you forgot a dot '.' between the table name and the *, thats becuase you are selecting id and code column from each table, you need to specify where are you selecting from when there is more then 1 options :
SELECT fruit.A,fruit.B, flower.C,flower.D, animal.E,animal.F,day.G,day.code
FROM day
LEFT JOIN fruit
ON day.code = fruit.code
LEFT JOIN flower
ON day.code = flower.code
LEFT JOIN animal
ON day.code = animal.code
ORDER BY day.code DESC;

MySQL query result fluctuating

My problem is more clear on this post: Select all categories with latest post, user, and topic information
——————————————————————————————————————————
I have a query that pulls a list of the categories for my forum along with the latest post in that category. The results come back as expected, except that sub_post information being pulled in the LEFT JOIN fp1 changes if if run the query several times.
I first noticed this problem when viewing my webpage and refreshing several times. The post that it is pulling fluctuates between 3 posts. I'm not sure how this is even possible, unless there is something wrong with the query.
Please, take a look at my query below and let me know if there is something I am doing wrong that might explain this odd behavior.
Cheers.
SELECT fc1.id AS cat_id, fc1.cat_name AS cat_name,
fc1.cat_description AS cat_description, fc1.cat_views as cat_views, fp1.*
FROM forum_categories as fc1
LEFT JOIN (SELECT fp2.id AS sub_post_id,
fp2.post_date as sub_post_date,
fp2.post_topic as sub_post_topic,
u2.id as sub_user_id, u2.username as sub_username,
ft2.topic_subject as sub_topic_subject, ft2.topic_cat as sub_topic_cat
FROM forum_posts as fp2
LEFT JOIN users as u2 on fp2.post_by = u2.id
LEFT JOIN forum_topics as ft2 on ft2.id = fp2.post_topic
LEFT JOIN forum_categories as fcats on fcats.id = ft2.topic_cat
ORDER BY fp2.id DESC)
as fp1 on fp1.sub_topic_cat = fc1.id
GROUP BY fc1.id;
EXPLAIN SELECT:
+----+-------------+------------+--------+-------------------------+-------------+---------+--------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+-------------------------+-------------+---------+--------------------+------+-------------+
| 1 | PRIMARY | fc1 | index | PRIMARY,cat_name_unique | PRIMARY | 8 | NULL | 3 | Using where |
| 1 | PRIMARY | <derived2> | ref | <auto_key0> | <auto_key0> | 9 | tpw.fc1.id | 9 | NULL |
| 2 | DERIVED | fp2 | index | NULL | PRIMARY | 8 | NULL | 92 | NULL |
| 2 | DERIVED | u2 | eq_ref | PRIMARY | PRIMARY | 8 | tpw.fp2.post_by | 1 | NULL |
| 2 | DERIVED | ft2 | eq_ref | PRIMARY | PRIMARY | 8 | tpw.fp2.post_topic | 1 | NULL |
| 2 | DERIVED | fcats | eq_ref | PRIMARY | PRIMARY | 8 | tpw.ft2.topic_cat | 1 | Using index |
+----+-------------+------------+--------+-------------------------+-------------+---------+--------------------+------+-------------+
I have 3 tables: forums_categories, forums_topics, and forums_posts. I am trying to list the categories along with the latest post in that category. The forums_post is linked to forums_topics by a post_topic and the forums_topics is linked to the forums_categories with a topic_cat.
This was solved by _pala on this other question: https://stackoverflow.com/a/30048334/4864675
I was going about the query wrong which accounted for the odd behavior. Thanks _pala!
Here's the SQL that worked it out for me provided by user _pala:
select fc.cat_name, fc.cat_description, fc.cat_views, u.username, fp.post_date, ft.topic_subject
from forum_categories fc
inner join forum_topics ft
on fc.id = ft.topic_cat
inner join forum_posts fp
on fp.post_topic = ft.id
inner join users u
on fp.post_by = u.id
inner join (
select topic_cat, max(fp.id) most_recent_post
from forum_topics ft
inner join forum_posts fp
on fp.post_topic = ft.id
group by topic_cat
) q
on q.topic_cat = ft.topic_cat
and fp.id = q.most_recent_post;
LEFT JOIN forum_categories as fcats on fcats.id = ft2.topic_cat
I believe the inclusion of that LEFT JOIN has no impact on the result other than to slow down processing. Remove it.
ORDER BY fp2.id DESC
That ORDER BY has no impact on the result because the GROUP BY will not care. Remove it.
If neither of those helps, then explain this:
The post that it is pulling fluctuates between 3 posts.
And please provide EXPLAIN SELECT ...

PHP MySQL joining two tables with conditional joins

So, I have a database that I am creating. It stores information about families and each family member. It then uses those records to associate invoices to either a family or family member.
My dilemma is that I need to list all of these invoices to a page under the families record i.e. create a list of invoices associated to either the family itself or an individual family member.
Table Structure
invoices
id | date_entered | invoice_date | invoice_number | invoice_amount | client_type | unique_id | supplier_type | supplier_id | category_id | childcare_hours
---+--------------+--------------+----------------+----------------+-------------+-----------+---------------+-------------+-------------+----------------
1 | 1411098397 | 1411048800 | 123 | 0.01 | 0 | 137 | 0 | 139 | 5 | NULL
families
id | ufi | last_name | address_1 | address_2 | city_id | phone | mobile | email | f_d_worker_1 | f_d_worker_2 | status_id | trans_date | entry_date | exit_date | eligible_date | active_date | lga_loc_id | facs_loc_id | ind_status_id | referral_id | active_status | comm_org_id | notes
---+----------+-----------------+-------------+-----------+---------+-------+--------+-------+--------------+--------------+-----------+------------+------------+-----------+---------------+-------------+------------+-------------+---------------+-------------+---------------+-------------+-------
1 | 1-XEWUDZ | Forsyth - Ennis | Skinner St. | NULL | NULL | NULL | NULL | NULL | 13 | NULL | 1 | NULL | 1341324000 | NULL | 1341842400 | 1342620000 | 7 | 1 | 3 | NULL | 1 | 1 | NULL
clients (family members)
id | upi | last_name | first_name | birthdate | sex | phone | mobile | email | indig_status_id | referral_id | relationship_id | preschool_id | family_id | notes
---+----------+-----------+------------+------------+-----+-------+--------+-------+-----------------+-------------+-----------------+--------------+-----------+------
1 | 1-XFCBBP | Ennis | Jason | 20/09/1996 | 1 | NULL | NULL | NULL | 3 | NULL | NULL | NULL | 1 | NULL
My current SQL looks like:
SELECT `invoices`.`id`, `invoices`.`date_entered`, `invoices`.`invoice_date`, `invoices`.`invoice_number`, `invoices`.`invoice_amount`, `invoices`.`client_type`, `invoices`.`unique_id`, `unique1`.`ufi`, `unique2`.`upi`, `unique1`.`last_name`, `invoices`.`supplier_type`, `invoices`.`supplier_id`, `suppliers`.`name`, `invoices`.`category_id`, `cat1`.`name`, `cat2`.`name`, `invoices`.`childcare_hours`
FROM `invoices`
LEFT OUTER JOIN `suppliers` ON `suppliers`.`id` = `invoices`.`supplier_id`
LEFT OUTER JOIN `categories` cat1 ON `cat1`.`id` = `invoices`.`category_id`
LEFT OUTER JOIN `preschool_types` cat2 ON `cat2`.`id` = `invoices`.`category_id`
LEFT OUTER JOIN `families` unique1 ON `unique1`.`id` = `invoices`.`unique_id`
LEFT OUTER JOIN `clients` unique2 ON `unique2`.`id` = `invoices`.`unique_id`
WHERE (`invoices`.`unique_id` = ? AND `unique1`.`ufi` = ?) LIMIT 0, 10
But what I need a query that checks the client_type column and if it equals 1 it needs to look in the clients table BUT it needs to look for members of the same family, identified by the id row in the families table
SOLUTION
Ok, so after much, much (much) screwing around and a little research. It appears that #cupid was correct (Although very brief in his answer).
And I will explain the solution better (in hope that this will help someone later).
The UNION option in MySQL (and most likely other SQL) allows you to combine the result sets of two (or more) SELECT queries, into one result set. This is extremely helpful if you have similar data, in separate tables that you may want to select easily and process as one request. Also helpful (in my case) for pagination, by allowing you to utilise SQL's LIMIT option.
One thing to take into consideration is that, the UNION syntax uses the columns from the first SELECT statement as the column names for all following queries, also you need to make sure that you have the same amount of columns selected in all queries for this to work.
(
SELECT
`invoices`.`id`,
`invoices`.`date_entered`,
`invoices`.`invoice_date`,
`invoices`.`invoice_number`,
`invoices`.`invoice_amount`,
`invoices`.`client_type`,
`invoices`.`unique_id`,
`clients`.`upi`,
`clients`.`last_name`,
`clients`.`family_id`,
`invoices`.`supplier_type`,
`invoices`.`supplier_id`,
`suppliers`.`name`,
`invoices`.`category_id`,
`cat1`.`name`,
`cat2`.`name`,
`invoices`.`childcare_hours`
FROM
(
`invoices`
LEFT OUTER JOIN `suppliers` ON `suppliers`.`id` = `invoices`.`supplier_id`
LEFT OUTER JOIN `categories` cat1 ON `cat1`.`id` = `invoices`.`category_id`
LEFT OUTER JOIN `preschool_types` cat2 ON `cat2`.`id` = `invoices`.`category_id`
LEFT OUTER JOIN `clients` ON `clients`.`id` = `invoices`.`unique_id`)
WHERE
`clients`.`family_id` = 47 AND `invoices`.`client_type` = 1
)
UNION
(
SELECT
`invoices`.`id`,
`invoices`.`date_entered`,
`invoices`.`invoice_date`,
`invoices`.`invoice_number`,
`invoices`.`invoice_amount`,
`invoices`.`client_type`,
`invoices`.`unique_id`,
`families`.`ufi`,
`families`.`last_name`,
`families`.`id`,
`invoices`.`supplier_type`,
`invoices`.`supplier_id`,
`suppliers`.`name`,
`invoices`.`category_id`,
`cat1`.`name`,
`cat2`.`name`,
`invoices`.`childcare_hours`
FROM `invoices`
LEFT OUTER JOIN `suppliers` ON `suppliers`.`id` = `invoices`.`supplier_id`
LEFT OUTER JOIN `categories` cat1 ON `cat1`.`id` = `invoices`.`category_id`
LEFT OUTER JOIN `preschool_types` cat2 ON `cat2`.`id` = `invoices`.`category_id`
LEFT OUTER JOIN `families` ON `families`.`id` = `invoices`.`unique_id`
WHERE
`invoices`.`unique_id` = 47 AND `invoices`.`client_type` = 0
)
Have you thought about using UNION?

MySQL INNER vs LEFT JOIN different order

Why do this two queries return different result set when they have the same ORDER BY.
Only difference in query is that first time I user INNER JOIN an it takes about 5 seconds.
Second time I used LEFT JOIN and it took 0.05 seconds. In both cases they return exactly 43.000 rows, but tck.id order is different and I can't figure out why or in which way?
SELECT tck.*, acc.ac_name
FROM support_tickets tck
INNER JOIN support_ticket_accounts acc USING (id_support_ticket_account)
WHERE tck.id_company = 2 AND tck.st_status = 1 ORDER BY tck.st_priority DESC
Edit:
SELECT tck.*, acc.ac_name
FROM support_tickets tck
LEFT JOIN support_ticket_accounts acc ON tck.id_support_ticket_account = acc.id_support_ticket_account
WHERE tck.id_company = 2 AND tck.st_status = 1
ORDER BY tck.st_priority DESC;
+----+-------------+-------+--------+---------------+------------+---------+-------------------------------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+------------+---------+-------------------------------+-------+-----------------------------+
| 1 | SIMPLE | tck | ref | id_company | id_company | 5 | const | 37586 | Using where; Using filesort |
| 1 | SIMPLE | acc | eq_ref | PRIMARY | PRIMARY | 4 | tck.id_support_ticket_account | 1 | |
+----+-------------+-------+--------+---------------+------------+---------+-------------------------------+-------+-----------------------------+
SELECT tck.*, acc.ac_name
FROM support_tickets tck
INNER JOIN support_ticket_accounts acc ON tck.id_support_ticket_account = acc.id_support_ticket_account
WHERE tck.id_company = 2 AND tck.st_status = 1
ORDER BY tck.st_priority DESC;
+----+-------------+-------+------+-------------------------------------+----------------------------+---------+-------------------------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+--------------------------------------+---------------------------+---------+-------------------------------+------+---------------------------------+
| 1 | SIMPLE | acc | ALL | PRIMARY | NULL | NULL | NULL | 5 | Using temporary; Using filesort |
| 1 | SIMPLE | tck | ref | id_company,id_support_ticket_account | id_support_ticket_account | 5 | acc.id_support_ticket_account | 2085 | Using where |
+----+-------------+-------+------+--------------------------------------+---------------------------+---------+-------------------------------+------+---------------------------------+
I think using temporary is responsible for the delay (but I don't see why it's necessary for one query and not the other one). I think creating multi-column index should help:
CREATE INDEX filter
ON support_tickets(id_company, st_status, st_priority)
USING BTREE;
If you just ORDER BY tck.st_priority DESC multiple different recordsets are posible and can be returned, for each of both cases (left or inner). That is because you must have a lot of records that has the same st_priority so any of them can came in no particular order
Add more fields to the order by clause to give any record unique possible position and you will have same order on both querys.

Categories