英文:
How to make an efficient mysql index for WHERE x > 0
问题
我有一个使用情况,我的表有几列:
CREATE TABLE stocks (
id INT,
warehouse_id INT,
product_id INT,
quantity INT,
updated_at DATETIIME
);
几乎所有我的查询都包括WHERE quantity > 0
和ORDER BY updated_at
。
例如:
WHERE quantity > 0
AND warehouse_id = 11
ORDER BY updated_at DESC
或者
WHERE quantity > 0
AND product_id = 1200
ORDER BY updated_at ASC
我知道我可以简单地在quantity
上添加一个索引,但这将阻止ORDER BY
使用索引。
是否有一种方法可以创建一个仅存储两个值的索引:quantity = 0
和quantity > 0
,以便我可以利用上面提到的两个规则?
例如,对于上面的查询:
CREATE INDEX idx_test1 ON stocks ("quantity > 0", product_id, updated_at)
CREATE INDEX idx_test2 ON stocks ("quantity > 0", warehouse_id, updated_at)
英文:
I have a use case where my table has a couple of columns:
CREATE TABLE stocks (
id INT,
warehouse_id INT,
product_id INT,
quantity INT,
updated_at DATETIIME
);
Almost all of my queries include WHERE quantity > 0
and ORDER BY updated_at
.
eg.
WHERE quantity > 0
AND warehouse_id = 11
ORDER BY updated_at DESC
or
WHERE quantity > 0
AND product_id = 1200
ORDER BY updated_at ASC
I know I can simply add an index on quantity, but that will prevent ORDER BY
from using the index.
Is there a way to make an index that only stores 2 values: quantity = 0
and quantity > 0
so I can take advantage of it with both rules I mentioned above?
eg. for queries above:
CREATE INDEX idx_test1 ON stocks ("quantity > 0", product_id, updated_at)
CREATE INDEX idx_test2 ON stocks ("quantity > 0", warehouse_id, updated_at)
答案1
得分: 3
以下是翻译好的部分:
从MySQL 8.0.13开始,您可以创建[一个功能性索引](https://dev.mysql.com/doc/refman/8.0/en/create-index.html#create-index-functional-key-parts),该索引使用函数或表达式。
您的伪代码:
CREATE INDEX idx_test1 ON stocks ("quantity > 0", product_id, updated_at);
将翻译为:
CREATE INDEX idx_test1 ON stocks ( ( quantity > 0 ), product_id, updated_at);
表达式 `quantity > 0` 会产生一个取决于条件是否满足的 `1` 或 `0` - 这是索引所使用的。
目前尚不确定这是否会实际改善查询的性能;索引通常不适合对 `0`/`1` 值进行索引,因为只有两种可能的值。您*可能*想尝试更改索引中列的顺序,将更具区分度的条件放在首位,所以也许是:
CREATE INDEX idx_test1 ON stocks ( product_id, updated_at, ( quantity > 0 ));
如果您的查询也使用了相反的排序方向,您可能还想使用带有 `updated_at desc` 的相同索引。
英文:
Starting MySQL 8.0.13, you can create a functional index, which makes use of a function or expression.
Your pseudo-code:
CREATE INDEX idx_test1 ON stocks ("quantity > 0", product_id, updated_at);
Would translate as:
CREATE INDEX idx_test1 ON stocks ( ( quantity > 0 ), product_id, updated_at);
Expression quantity > 0
yields 1
or 0
depending on whether the condition is fulfilled - which the index uses.
It is unsure whether this will actually improve the performance of the query; 0
/1
values are typically inefficient to index, because there are just two possible values. You might want to try changing the order of the columns in the index, to put a more discriminating criteria first, so maybe:
CREATE INDEX idx_test1 ON stocks ( product_id, updated_at, ( quantity > 0 ));
You might also want to have the same index with updated_at desc
, if your queries use that sort direction as well.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论