2013-07-06 90 views
0

,如果我有在where子句中以下指標:不使用WHERE子句

(approps_precio * moneda_valor BETWEEN 2000 AND 6000) 

它不使用idx_approps_precio指數。

(approps_precio BETWEEN 2000 AND 6000) 

確實非常好。

有沒有辦法添加*操作,仍然使用索引?。

在此先感謝。

+0

您是否考慮過將產品'approps_precio * moneda_valor'存儲在自己的(n索引)列中?您可以使用[triggers](http://dev.mysql.com/doc/en/triggers.html)確保其值與底層列保持一致。 – eggyal

回答

0

*操作使得您的值爲0,因此當moneda_valor爲空時,該值會在範圍外。所以,你可以把它改寫爲:

approps_precio BETWEEN 2000 AND 6000 and moneda_valor IS NOT NULL

1

moneda_valor恆定?否則,當您查找approps_precio的值乘以moneda_valor時,approps_precio上的索引無用。

+0

不是一個常量,是一個前一個連接檢索的值。 – KillDash9

1

我一直在四處尋找一些官方文件來支持保羅杜波依斯(雖然MySQL文檔團隊的一員)在他的著作MySQL (Developer's Library)的第五章「查詢優化」說:

使索引列獨立於比較表達式中。如果在函數調用中使用列或者作爲算術表達式中更復雜的術語的一部分,MySQL不能使用索引,因爲它必須爲每一行計算表達式的值。有時候這是不可避免的,但很多時候你可以重寫查詢來讓索引列自行出現。

我能找到的最好的是在內幕手冊上Optimizer Transpositions部分:

然而,MySQL不支持,其中算術存在換位。因此:

WHERE 5 = -column1 

不被視爲相同:

WHERE column1 = -5 

換位到窗體列的表達式=常數是理想的的索引查找。

在這種情況下,人們可以通過除以moneda_valorapprops_precio利用指數通過重寫過濾條件:

WHERE approps_precio BETWEEN 2000/moneda_valor AND 6000/moneda_valor 

注意,MySQL將仍然需要評估師爲每個記錄,所以我不相信會保存多少。