2011-10-31 27 views
2

我有一個數字的大型數據庫,我在尋找一個匹配之間:聲明失蹤指數之間在某些情況下

例如:

1112203488 

我的表看起來像這樣:

| sATON | eATON | info |

我有sATON和伊頓兩隻指數的(命名爲S和E)

所以我的SQL如下:

SELECT * 
FROM `data2` 
FORCE INDEX (s, e) 
WHERE 1112203488 
BETWEEN `sATON` 
AND `eATON`; 

所以通常發生在使用索引的查詢將接近於零時間(0.02)。但是,有時看起來MySQL中的表格統計信息正在做出全表掃描的決定,而不管我強制使用SQL中的索引。這是一個巨大的性能影響,因爲它將查詢從0.02秒延長到120秒。

這裏有一些樣品是跑得快(使用索引):

67372289 
134744072 

而緩慢的:

1112203488 
1348203839 

如果有幫助的索引使用BTREE。

+0

多少行是慢查詢返回(什麼表的百分比),VS多少行(和百分比)快的人正在返回?表格統計信息是否準確並且是最新的? –

+0

這兩個索引不能同時使用。無論是其中一個還是其他。 –

+0

@MikeChristensen所有的查詢都會返回一個,這些數據是最新的。 – Benjojo

回答

1

如果任何此類查詢將返回最大一行,這意味着(sATON, eATON)範圍不重疊。

因此,且僅當範圍是不重疊的,您可以使用此查詢代替:

SELECT * 
FROM data2 
WHERE sATON = 
     (SELECT MAX(sATON) 
     FROM data2 
     WHERE sATON <= 1112203488 
    ) 
    AND eATON = 
     (SELECT MIN(eATON) 
     FROM data2 
     WHERE eATON >= 1112203488 
    ) 

,甚至這個(這將需要只使用一個索引,sATON一個):

SELECT * 
FROM data2 
WHERE sATON = 
     (SELECT MAX(sATON) 
     FROM data2 
     WHERE sATON <= 1112203488 
    ) 
    AND eATON >= 1112203488 
+0

+1不錯!這樣你可以使用兩個索引。 –

1

正如ypercube指出的,只有一個索引可以用於當前查詢。 從您的執行計劃中,我可以看到它使用s索引,這意味着它會掃描值大於sAton的所有行。對於較高的值,這將是幾乎所有值,使其與全表掃描一樣低效。

我會用ypercubes建議的解決方案,它應該能夠有效地使用這兩個索引。

使用綁定變量有幾個目的:

  1. 消除了SQL injection
  2. 風險允許數據庫重用編譯SQL語句
  3. 減少不同問題的數量,更好地利用datbase緩存爲最近使用的問題

我主要與甲骨文合作,所以我不知道如何有效的2和3是用於MySQL。

如果你想知道如何使用它們,只是谷歌:mysql bind variable example +your programming language

相關問題