簡體   English   中英

需要幫助來提高SQL查詢性能

[英]Need help improving sql query performance

這是我簡化的歷史記錄表結構:

id | property_id | price   | created_at          | updated_at          | deleted_at
1  |      1      |   100   | 2016-04-10 01:00:00 | 2016-04-10 01:00:00 | NULL
2  |      1      |   300   | 2016-04-10 01:00:00 | 2016-04-10 01:00:00 | NULL
3  |      1      |   300   | 2016-04-10 02:00:00 | 2016-04-10 02:00:00 | NULL
4  |      2      |   200   | 2016-04-10 03:00:00 | 2016-04-10 03:00:00 | NULL
1  |      2      |   150   | 2016-04-10 04:00:00 | 2016-04-10 04:00:00 | NULL

我需要:

  1. 我想獲取符合特定條件的記錄,尤其是created_at字段在過去24小時內
  2. 我需要獲取#1中的記錄之前的記錄
  3. 進一步篩選結果為#1,以使其價格列在記錄的歷史記錄中具有不同的值,而不是-1

到目前為止,這是我的查詢,但是有點慢:

SELECT *
  FROM `history` `t1`
 WHERE `t1`.`created_at` >= '2016-04-13 00:00:00'
   AND `t1`.`created_reason` = 'Scraped'
   AND `t1`.`price` > -1
   AND (SELECT `t2`.`price`
          FROM `history` `t2`
         WHERE `t2`.`property_id` = `t1`.`property_id`
           AND `t2`.`created_at` < `t1`.`created_at`
           AND `t2`.`price` > -1
         ORDER BY DATE(`t2`.`created_at`) DESC
         LIMIT 1
       ) <> `t1`.`price`
 GROUP BY `t1`.`property_ad_id`

關於如何提高性能的任何建議?

這里有一些建議。

使用EXPLAIN獲取查詢執行計划。

從t1返回的每一行都將執行相關子查詢。 這會大大降低性能。

相關的子查詢對一個函數的結果執行ORDER BY,這意味着MySQL必須對滿足謂詞的每一行都評估該表達式,然后進行排序操作。 (使用LIMIT 1,MySQL可能不必完全對整個集合進行排序,但是它確實需要至少進行一次傳遞才能獲得第一行。)

因為DATE()函數停止了時間成分,所以如果t2中有多行滿足其他謂詞(早期created_at),同一最新日期和不同時間,則不確定將首先對那些行進行排序。 您可能會從04:00開始行而不是從17:00開始行

建議:引用裸露的列,並確保適當的索引可用。

建議:獲取在創建的“最大值”(有效利用索引)

建議:在一周的48小時,72小時內,將您要在t2中查找的前一行的下限設置為下限?

建議:確保適合於t1上的外部查詢和t2上的子查詢的索引。 (可能那些將需要兩個不同的索引)


作為改進的第一步,需要進行一些小調整。

SELECT t1.*
  FROM history t1
 WHERE t1.created_at >= '2016-04-13 00:00:00'
   AND t1.created_reason = 'Scraped'
   AND t1.price > -1
   AND t1.price <> 
       (
         SELECT t2.price
           FROM history t2
          WHERE t2.property_id = t1.property_id
            AND t2.created_at  < t1.created_at
            AND t2.created_at  > t1.created_at + INTERVAL -30 DAY
            AND t2.price > -1
          ORDER BY t2.created_at DESC
          LIMIT 1
       )
 GROUP BY t1.property_ad_id

最合適的指標可能是

... ON history(created_reason,created_at,property_id,price)
... ON history(property_id,created_at,price)

為了優化GROUP BY(避免進行排序操作),我們還可以考慮嘗試使用帶有property_ad_id前導列的索引。 這是一個很長的路,但可能值得一試,以了解EXPLAIN是否顯示它正在使用...

... ON history(property_ad_id,created_reason,created_at,property_id,price)

暫無
暫無

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

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