我正在尽可能快地执行SQL查询。
只有一个表有1,000万条记录,该表有3个索引用于更快的读取,但不幸的是,我想从其中选择的列还没有。
让我解释一下:我想从表bugs(id, token, title, category, device, reported_at, created_at, updated_at)中选择标题:
我在做什么:SELECT title FROM (SELECT id FROM bugs WHERE reported_at = '2020-08-30' and token = 'token660')
虽然我使用了两个索引reported_at和token,但是它很慢,但是如何加快速度呢?
以下是索引:
{
"records": [
{
"Table": "bugs",
"Non_unique": 0,
"Key_name": "PRIMARY",
"Seq_in_index": 1,
"Column_name": "id",
"Collation": "A",
"Cardinality": 9791826,
"Sub_part": null,
"Packed": null,
"Null": "",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": ""
},
{
"Table": "bugs",
"Non_unique": 1,
"Key_name": "index_bugs_on_category_and_token_and_reported_at",
"Seq_in_index": 1,
"Column_name": "category",
"Collation": "A",
"Cardinality": 1,
"Sub_part": null,
"Packed": null,
"Null": "YES",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": ""
},
{
"Table": "bugs",
"Non_unique": 1,
"Key_name": "index_bugs_on_category_and_token_and_reported_at",
"Seq_in_index": 2,
"Column_name": "token",
"Collation": "A",
"Cardinality": 29946,
"Sub_part": null,
"Packed": null,
"Null": "YES",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": ""
},
{
"Table": "bugs",
"Non_unique": 1,
"Key_name": "index_bugs_on_category_and_token_and_reported_at",
"Seq_in_index": 3,
"Column_name": "reported_at",
"Collation": "A",
"Cardinality": 6085027,
"Sub_part": null,
"Packed": null,
"Null": "YES",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": ""
}
]
}发布于 2022-06-02 18:32:23
In MySQL,多列索引只能使用最左边的列.其他数据库没有此限制。。
这是因为MySQL索引(默认情况下)是B-树。多列索引是一棵树.要使用索引(category, token, reported_at) MySQL,首先必须在类别树中找到一个类别,然后在该类别中会有一个令牌子树,最后在该类别和令牌中有一个reported_at的子树。
在您的示例中,在(category, token, reported_at)上有一个多列索引。如果只按类别进行搜索,MySQL可以使用索引。或者按照类别和标记,MySQL可以使用索引。或按类别、令牌和reported_at分类。
您正在按令牌和reported_at进行搜索,但由于没有按类别进行搜索,MySQL将不使用索引。它必须扫描类别索引中的每个条目,以获得匹配的令牌。其他数据库在如何使用索引方面更加灵活,可能无论如何都会尝试这样做,但MySQL不会。
通常,有两个以上列的索引的价值是值得怀疑的。
发布于 2022-06-02 02:41:02
您需要使用搜索条件的列创建索引。在这种情况下:
CREATE INDEX search_index
ON bugs (reported_at, token);既然你是用等号搜索,这应该是快速的。查询必须是:
SELECT title FROM bugs WHERE reported_at = '2020-08-30' and token = 'token660'如果无法更改数据库,则可以分别选择行,将它们相交,然后获得标题:
SELECT r.title
FROM (
SELECT * FROM bugs WHERE reported_at = '2020-08-30'
) r
JOIN (
SELECT id FROM bugs WHERE token = 'token660'
) t
ON r.id = t.id发布于 2022-06-02 23:02:55
SELECT id
FROM bugs
WHERE reported_at = '2020-08-30'
and token = 'token660'需要这个综合索引:INDEX(token, reported_at)
我不知道其他关于category或title的胡言乱语是什么。
https://stackoverflow.com/questions/72469648
复制相似问题