[英]How to improve SQL query speed on Date in a larger Database
我正在嘗試優化 SQL 查詢以提高其執行速度。 我已經發現 Date 列是問題所在。 當我運行此查詢時,包括數據庫中的日期:
SELECT p.*, preis.preis
FROM produkt p INNER JOIN (SELECT * FROM preis WHERE DATE(preis.Datum) = CURDATE()) preis ON p.id = preis.produkt_id
WHERE artikel_id IN (SELECT artikel_id FROM produkt WHERE haendler_id = 1)
需要 28 秒才能得到結果。 但是,當我將 INNER JOIN select 的 WHERE-Clause 更改為id > 256981
256981 時,我得到了相同的結果,它只需要 0,062 秒。
SELECT p.*, preis.preis
FROM produkt p INNER JOIN (SELECT * FROM preis WHERE preis.id > 256981) preis ON p.id = preis.produkt_id
WHERE artikel_id IN (SELECT artikel_id FROM produkt WHERE haendler_id = 1)
這是一個很大的區別。
我已經閱讀了一些關於 INDEX 和不同 INDEX 類型的內容,但是我找不到以正確方式對 DATE 字段進行索引的解決方案。 或者還有其他方法可以改善這樣的查詢嗎?
SELECT p.*, q.preis
FROM ( SELECT artikel_id FROM produkt WHERE haendler_id = 1 ) AS a
JOIN produkt p USING(artikel_id)
INNER JOIN
( SELECT preis
FROM preis
WHERE Datum >= CURDATE()
AND Datum < CURDATE() + INTERVAL 1 DAY
) AS q ON p.id = q.produkt_id
並有這些索引:
preis: INDEX(Datum, produkt_id, preis)
preis: INDEX(produkt_id, Datum, preis)
produkt: INDEX(haendler_id, artikel_id)
produkt: INDEX(artikel_id)
如果 produkt 只能有一個preis
,那么還有另一種選擇。
我們確實需要查看SHOW CREATE TABLE
檢查數據類型、主鍵和其他內容。
您是否嘗試過在沒有日期 function 的datum
上直接使用無子查詢和條件的連接,如下所示:
SELECT p.*, preis.preis
FROM produkt p
INNER JOIN preis ON p.id = preis.produkt_id
WHERE preis.Datum >= CURDATE() and preis.Datum < DATE_ADD(CURDATE(), INTERVAL 1 DAY)
AND artikel_id IN (SELECT artikel_id FROM produkt WHERE haendler_id = 1)
您可以在preis.Datum
上創建索引,如下所示:
CREATE INDEX preis_indx_01 ON preis(Datum);
注意:如果在連接中經常使用produkt_id
,您也可以考慮在其上創建索引。
主要問題是當您使用 mysql 任何構建 function 時,如CURDATE()這會使查詢變慢,因此請盡量避免它,因此請嘗試像這樣更新您的查詢
// first make today date if your code is php then $today = date('Y-m-d');
then use this in mysql
SELECT p.*, preis.preis
FROM produkt p INNER JOIN (SELECT * FROM preis WHERE DATE(preis.Datum) = '$today')
preis ON p.id = preis.produkt_id
WHERE artikel_id IN (SELECT artikel_id FROM produkt WHERE haendler_id = 1)
如果你也避免DATE會更好
SELECT p.*, preis.preis
FROM produkt p INNER JOIN (SELECT * FROM preis WHERE preis.Datum = '$today')
preis ON p.id = preis.produkt_id
WHERE artikel_id IN (SELECT artikel_id FROM produkt WHERE haendler_id = 1)
我想這會對你有所幫助
首先,不要使用子查詢。 其次,我也不推薦in
所以:
SELECT p.*, pp.preis
FROM produkt p INNER JOIN
preis pp
ON p.id = pp.produkt_id
WHERE p.Datum >= CURDATE() AND
p.Datum < CURDATE() + INTERVAL 1 DAY AND
EXISTS (SELECT 1
FROM produkt p2
WHERE p2.artikel_id = p.artikel_id AND
p2.haendler_id = 1
);
然后對於此查詢,您需要product(artikel_id, haendler_id)
和preis(Datum, product_id)
上的索引。
我相信您在id
列上有索引,但在 data 列上沒有索引,在該列上定義索引,您應該得到幾乎相同的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.