[英]Query with OR making query execution SLOW
I am a newbie and have trouble with a OR query! 我是新手,或遇到OR查询问题!
When I do it without OR the execution time is: 0.02 Seconds 当我不使用OR进行操作时,执行时间为:0.02秒
SELECT DISTINCT p.*,
ht.html_title,
ht.html_content,
sc.sub_cat_name,
sc.main_cat_id,
us.username,
c.name AS cityname
FROM ad_product p,
ad_html ht,
ad_catagory_sub sc,
ad_user us,
ad_cities c
WHERE ( ht.ad_id = p.id )
AND ( sc.sub_cat_id = p.category )
AND ( us.id = p.user_id )
AND ( p.category = 216 )
AND ( p.status = 'active' )
AND ( c.id = p.city )
AND ( p.city = 135 )
ORDER BY p.created_at DESC;
And when I am trying it with OR condition then it takes about 4.70 Seconds 当我在OR条件下尝试时,大约需要4.70秒
SELECT DISTINCT p.*,
ht.html_title,
ht.html_content,
sc.sub_cat_name,
sc.main_cat_id,
us.username,
c.name AS cityname
FROM ad_product p,
ad_html ht,
ad_catagory_sub sc,
ad_user us,
ad_cities c
WHERE ( ht.ad_id = p.id )
AND ( sc.sub_cat_id = p.category )
AND ( us.id = p.user_id )
AND ( p.category = 216
OR p.parent_category = 216 )
AND ( p.status = 'active' )
AND ( c.id = p.city )
AND ( p.city = 135 )
ORDER BY p.created_at DESC;
EXPLAIN: 说明:
+----+-------------+-------+------------+-------------+--------------------------------------------------------------------------------+--------------------------+---------+---------------------------+-------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------------+--------------------------------------------------------------------------------+--------------------------+---------+---------------------------+-------+----------+----------------------------------------------------+
| 1 | SIMPLE | c | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using temporary; Using filesort |
| 1 | SIMPLE | p | NULL | index_merge | PRIMARY,id,parent_category,city,user_id_2,category,status,id_2,id_3,category_2 | category,parent_category | 4,4 | NULL | 67889 | 4.74 | Using union(category,parent_category); Using where |
| 1 | SIMPLE | sc | NULL | eq_ref | PRIMARY | PRIMARY | 4 | abc_classified.p.category | 1 | 100.00 | NULL |
| 1 | SIMPLE | us | NULL | eq_ref | PRIMARY | PRIMARY | 4 | abc_classified.p.user_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | ht | NULL | ref | ad_id | ad_id | 4 | abc_classified.p.id | 1 | 100.00 | NULL |
+----+-------------+-------+------------+-------------+--------------------------------------------------------------------------------+--------------------------+---------+---------------------------+-------+----------+----------------------------------------------------+
I think I have proper indexes defined, can someone point out what am i doing wrong ? 我认为我已经定义了适当的索引,有人可以指出我做错了什么吗? or how can i decrease execution time ?
或如何减少执行时间? Also why this is happening for my knowledge ?
另外,据我所知为什么会发生这种情况?
I think your query would benefit from a union rather than an or. 我认为您的查询将从联合而不是or中受益。 This creates 2 sets of data.
这将创建2组数据。 One on the categoryid and the other on the parent categoryid.
一个在categoryid上,另一个在父categoryid上。 Which will be quicker than defining 2 negative sets.
这比定义2个否定集要快。 One set without the categoryid = 216 and one without the parent categoryid = 216.
一组没有categoryid = 216的集合,而另一组没有父categoryid = 216的集合。
SELECT DISTINCT p1.*,
ht.html_title,
ht.html_content,
sc.sub_cat_name,
sc.main_cat_id,
us.username,
c.name AS cityname
FROM ad_product p1 inner join ad_html ht on ht.ad_id = p1.id
inner join ad_category_sub sc on sc.sub_cat_id = p1.category
inner join ad_user us on us.id = p1.user_id
inner join ad_cities c on c.id = p1.city
WHERE ( p1.status = 'active' )
AND ( p1.city = 135 )
AND ( p1.category = 216)
UNION
SELECT DISTINCT p.*,
ht.html_title,
ht.html_content,
sc.sub_cat_name,
sc.main_cat_id,
us.username,
c.name AS cityname
FROM ad_product p
inner join ad_html ht on ht.ad_id = p.id
inner join ad_category_sub sc on sc.sub_cat_id = p.category
inner join ad_user us on us.id = p.user_id
inner join ad_cities c on c.id = p.city
WHERE ( p.status = 'active' )
AND ( p.city = 135 )
AND (p.parent_category = 216)
ORDER BY p.created_at DESC;
@Dwight Reynoldson Answers works just fine on SQL Server and I got a workaround for "ORDER BY" issue on MySQL. @Dwight Reynoldson Answers在SQL Server上工作正常,我在MySQL上遇到了“ ORDER BY”问题的解决方法。 All I did was
ORDER BY created_at DESC
instead of ORDER BY p.created_at DESC
It was the p which was creating all the issue. 我所做的只是由
ORDER BY created_at DESC
而不是ORDER BY p.created_at DESC
造成所有问题的是p。
Answer: 回答:
SELECT DISTINCT p1.*,
ht.html_title,
ht.html_content,
sc.sub_cat_name,
sc.main_cat_id,
us.username,
c.name AS cityname
FROM ad_product p1 inner join ad_html ht on ht.ad_id = p1.id
inner join ad_category_sub sc on sc.sub_cat_id = p1.category
inner join ad_user us on us.id = p1.user_id
inner join ad_cities c on c.id = p1.city
WHERE ( p1.status = 'active' )
AND ( p1.city = 135 )
AND ( p1.category = 216)
UNION
SELECT DISTINCT p.*,
ht.html_title,
ht.html_content,
sc.sub_cat_name,
sc.main_cat_id,
us.username,
c.name AS cityname
FROM ad_product p
inner join ad_html ht on ht.ad_id = p.id
inner join ad_category_sub sc on sc.sub_cat_id = p.category
inner join ad_user us on us.id = p.user_id
inner join ad_cities c on c.id = p.city
WHERE ( p.status = 'active' )
AND ( p.city = 135 )
AND (p.parent_category = 216)
ORDER BY created_at DESC;
When you define exact values in where conditions, SQL uses a hash join
. 当您在where条件中定义精确值时,SQL使用
hash join
联接。 So it is much more faster than other joins. 因此,它比其他联接要快得多。 When you change it to a non exact value condition ( X OR Y ), it becomes slow.
当您将其更改为非精确值条件(X或Y)时,它变慢。
The solution is to make an index
in order to decrease the records to be searched. 解决方案是建立
index
,以减少要搜索的记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.