簡體   English   中英

使用OR查詢使查詢執行緩慢

[英]Query with OR making query execution SLOW

我是新手,或遇到OR查詢問題!

當我不使用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;

當我在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;

說明:

+----+-------------+-------+------------+-------------+--------------------------------------------------------------------------------+--------------------------+---------+---------------------------+-------+----------+----------------------------------------------------+
| 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                                               |
+----+-------------+-------+------------+-------------+--------------------------------------------------------------------------------+--------------------------+---------+---------------------------+-------+----------+----------------------------------------------------+

我認為我已經定義了適當的索引,有人可以指出我做錯了什么嗎? 或如何減少執行時間? 另外,據我所知為什么會發生這種情況?

我認為您的查詢將從聯合而不是or中受益。 這將創建2組數據。 一個在categoryid上,另一個在父categoryid上。 這比定義2個否定集要快。 一組沒有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在SQL Server上工作正常,我在MySQL上遇到了“ ORDER BY”問題的解決方法。 我所做的只是由ORDER BY created_at DESC而不是ORDER BY p.created_at DESC造成所有問題的是p。

回答:

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;

當您在where條件中定義精確值時,SQL使用hash join聯接。 因此,它比其他聯接要快得多。 當您將其更改為非精確值條件(X或Y)時,它變慢。

解決方案是建立index ,以減少要搜索的記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM