首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何快速选择SQL查询?

如何快速选择SQL查询?
EN

Stack Overflow用户
提问于 2022-06-02 01:25:10
回答 3查看 167关注 0票数 0

我正在尽可能快地执行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,但是它很慢,但是如何加快速度呢?

以下是索引:

代码语言:javascript
复制
{
    "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": ""
        }
    ]
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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不会。

用索引,卢克MySQL中多列索引的一个很好的解释

通常,有两个以上列的索引的价值是值得怀疑的。

因此,就像以前一样,答案是在您正在搜索的字段上创建一个新的索引。或者使用更好的数据库

票数 0
EN

Stack Overflow用户

发布于 2022-06-02 02:41:02

您需要使用搜索条件的列创建索引。在这种情况下:

代码语言:javascript
复制
CREATE INDEX search_index 
ON bugs (reported_at, token);

既然你是用等号搜索,这应该是快速的。查询必须是:

代码语言:javascript
复制
SELECT title FROM bugs WHERE reported_at = '2020-08-30' and token = 'token660'

如果无法更改数据库,则可以分别选择行,将它们相交,然后获得标题:

代码语言:javascript
复制
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
票数 0
EN

Stack Overflow用户

发布于 2022-06-02 23:02:55

代码语言:javascript
复制
SELECT  id
    FROM  bugs
    WHERE  reported_at = '2020-08-30'
      and  token = 'token660'

需要这个综合索引:INDEX(token, reported_at)

我不知道其他关于categorytitle的胡言乱语是什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72469648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档