2013-08-12 93 views
0

比方說,你有一個查詢一樣,如何使用> =和<=時使用索引MySQL表?

select ID, REGION, START, END from COORD_SYSTEM 
where REGION=? and TYPE=? and START >= ? and END <= ?; 

而且我們說這個表有大約50,000行。 REGION列有500個不同的值,TYPE列有50個不同的值。 ID列是主鍵。

索引表的最佳方法是什麼?我不太確定是否可以通過> =和< =符號實現覆蓋索引的。這裏有幾個選項:

  1. 上COORD_SYSTEM(區,TYPE)
  2. 上COORD_SYSTEM創建索引(區,類型,起始)
  3. 上COORD_SYSTEM(區,類型,開始,結束創建索引創建索引)

更新 - 這裏的解釋聲明:

  id: 1 
    select_type: SIMPLE 
     table: COORD_SYSTEM 
     type: range 
possible_keys: indx_A 
      key: indx_A 
     key_len: 50 
      ref: NULL 
     rows: 590 
     Extra: Using where 
1 row in set (0.00 sec) 
+0

我會說3應該是更好的,你有沒有嘗試過一些測試數據與大量的行? –

+0

使用選項3,它應該只能在索引上運行。另外選項2和3應具有相同數量的掃描行。你可以發佈EXPLAIN的嗎? – Vatev

+0

您是否嘗試過'在COORD_SYSTEM上創建索引(REGION,TYPE,START,END desc)'? –

回答

1

沒有理由,你不能使用範圍運營商覆蓋索引。挑戰(對於非覆蓋索引)是優化器可能認爲如果範圍很大,全面掃描可能會導致更少的頁面讀取次數,並且該索引不會用於某些查詢。同樣,對於某些參數值,如果覆蓋索引不比掃描某些參數集合好得多,則優化器可以選擇進行全面掃描。

因此,考慮到問題中的描述,實際上不可能爲所有情況提供最佳解決方案。

我傾向於這樣的事情做的是:

  • 創建數據庫
  • 猜測哪個指數威力做的工作的副本,並創建一個索引。
  • EXPLAIN幾個查詢使用不同大小的範圍(多個範圍需要更多的I/O要回表數據,如果你還沒有涵蓋查詢,所以你應該嘗試常見的尺寸和異常值)
  • 降指數和以不同的順序與列不同的覆蓋索引嘗試另一種,也許

你甚至可以選擇創建兩個或多個具有不同的訂單領域覆蓋索引,假設你運行該查詢相當多的時間比相應的INSERT s或UPDATE s,並且索引的大小不是磁盤空間使用的一個因素。

+0

謝謝!關於重新排序索引字段的最後一個提示非常有用:它減少了大量檢查的行數。 – ktm5124

1

您可以將索引視爲通過索引列中的值對行進行預先排序的一種方式。索引可用於與>=<=進行比較,方法與=相同。

您的選項3是可能是最好的指數,因爲所有的WHERE條件都可以通過查看索引來檢查。 無論它實際上是最好的指數取決於你的數據集,因爲,例如,如果你的大部分記錄有end一個非常大的價值,所有記錄將符合條件WHERE end <= ?和索引將是對這一很少使用的場(和優化器可以決定不使用索引這個領域,因爲它會導致沒有「投資回報率」的開銷)

0

你正在尋找的是BETWEEN命令,你不需要START和END ..你可以在只有1個表格行之間。

SELECT ID, REGION, START, END from COORD_SYSTEM WHERE REGION=? and TYPE=? BETWEEN 100 and 200; 
+0

否...您可以從查詢中看到START和END是表中的兩個單獨列,並且我傳遞了兩個單獨的參數以與之進行比較。 – ktm5124

相關問題