簡體   English   中英

指示MySQL將WHERE子句應用於上一個WHERE子句返回的行

[英]Instructing MySQL to apply WHERE clause to rows returned by previous WHERE clause

我有以下查詢:

  SELECT dt_stamp
    FROM claim_notes
   WHERE type_id             = 0
     AND dt_stamp           >= :dt_stamp
     AND DATE( dt_stamp )    = :date
     AND user_id             = :user_id
     AND note             LIKE :click_to_call
   ORDER BY dt_stamp
   LIMIT 1

claim_notes表大約有一百萬行,因此該查詢運行非常緩慢,因為它必須針對未索引的note列進行搜索(我對此無能為力)。 我知道當應用type_iddt_stampuser_id條件時,我將針對約60行而不是50萬行進行搜索。 但是MySQL似乎並沒有按順序應用它們。 我想做的是看看是否有一種方法告訴M​​ySQL僅將note LIKE :click_to_call條件應用於滿足前一個條件的行,以便它不搜索具有此條件的所有行。

我想出的是這樣的:

  SELECT dt_stamp
    FROM (
            SELECT *
              FROM claim_notes
             WHERE type_id           = 0
               AND dt_stamp         >= :dt_stamp
               AND DATE( dt_stamp )  = :date
               AND user_id           = :user_id
         )
     AND note LIKE :click_to_call
   ORDER BY dt_stamp
   LIMIT 1

這有效並且非常快。 我只是想知道這是否是正確的方法,或者是否有更正式的方法來處理它。

不要使用派生表解決方案,因為它不具有性能。 我對擁有=>=運算符MySQL首先適合LIKE感到驚訝。

無論如何,我會說您可以嘗試在這些字段上添加一些索引,然后看看會發生什么:

ALTER TABLE claim_notes ADD INDEX(type_id, user_id);
ALTER TABLE claim_notes ADD INDEX(dt_stamp);

后一個索引實際上並不會改善對索引的搜索,而是會改善結果的排序。

當然,有一個EXPLAIN查詢將幫助。

不必這樣做。 如果您的WHERE子句中有多個用AND分隔的術語,則MySQL優化器可以處理它。 基本上,它知道如何做“適用所有你可以使用索引,那么只有到剩下的行申請未索引表達式的條件。”

但是選擇正確的索引很重要。 多列索引最適合一系列AND項,而不是單個索引。 MySQL可以應用索引交集,但這要比使用單個索引查找相同的行要低得多。

一些邏輯規則適用於創建多列索引:

  • 與非唯一列上的條件相比,唯一列上的條件優先。

  • 相等條件( = )優先於范圍( >=INBETWEEN!=等)。

  • 索引中的第一列用於范圍條件之后,后續列將不使用索引。

  • 大多數情況下,在列上搜索函數的結果(例如DATE(dt_stamp) )不會使用索引。 在這種情況下,最好存儲DATE數據類型並使用=而不是>=

  • 如果條件匹配大於表的20%,MySQL可能會決定跳過索引並繼續進行表掃描。

以下是我本人和Percona同事的一些網絡研討會,以幫助解釋索引設計:

您可以免費獲得這些網絡研討會的幻燈片,並免費觀看錄像,但是錄像需要注冊。

暫無
暫無

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

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