簡體   English   中英

如何提高較大數據庫中日期的 SQL 查詢速度

[英]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.

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