首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >where子句与order子句之间的MySQL索引

问where子句与order子句之间的MySQL索引
EN

Stack Overflow用户
提问于 2013-06-12 22:43:27
回答 1查看 1.4K关注 0票数 2

我的桌子结构如下:

代码语言:javascript
复制
CREATE TABLE test (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,

    field_1 VARCHAR(60) NOT NULL,
    field_2 INT(10) UNSIGNED NULL,
    field_3 INT(10) UNSIGNED NULL,
    field_4 INT(10) UNSIGNED NULL,
    field_5 CHAR(2) NULL,
    field_6 INT(10) UNSIGNED NOT NULL,

    rank TINYINT(2) NOT NULL DEFAULT '0',   
    status TINYINT(3) NOT NULL DEFAULT '0',

    PRIMARY KEY (id),
    INDEX (status)

) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = MyISAM;

在上面的表中,字段rank和status的整数值分别在0-9和0-4之间。

目前,表中填充了大约950 K的数据,我正在尽可能地优化我的查询。

基本上,我需要使用where子句在字段rank上选择带有降序顺序的字段。

例如,下面是一些sql查询:

代码语言:javascript
复制
SELECT field_1, field_2, field_3 FROM test WHERE field_1 = 'data1' && status IN ('0', '1', '2') ORDER BY rank DESC LIMIT 0, 20;
SELECT field_1, field_2, field_3 FROM test WHERE field_2 = '5' && status IN ('1', '2') ORDER BY rank DESC LIMIT 0, 20;
SELECT field_1, field_2, field_3 FROM test WHERE field_5 = 'US' && status IN ('0', '2') ORDER BY rank DESC LIMIT 0, 20;

在上面的查询中,ORDER BY rank DESC非常重要。因此,我很困惑是应该在单列还是多列上添加索引。

有人能给我建议最好的解决办法吗。

EN

回答 1

Stack Overflow用户

发布于 2013-06-12 23:49:28

您的关键问题是,超过950 k行的status列有多达4个不同的值。在BTREE指数上,这将是一个真正的痛苦处理。

对于上述3个查询使用的一些更有效的索引可能如下

代码语言:javascript
复制
INDEX forQuery1 ( field_1 , status , rank ) USING BTREE,
INDEX forQuery2 ( field_2 , status , rank ) USING BTREE,
INDEX forQuery3 ( field_5 , status , rank ) USING BTREE,

您会发现,第二个查询尤其应该受益,但是您仍然会遇到这样的问题:数据集大小的数据差异非常小,而且MySQL很可能会退回到表扫描,尽管您的解释可能会显示出减少这种影响的限制。但是,上述索引应该适合确定要返回的行。

有关MySQL如何使用索引的更多信息,请查看13.1.13.创建索引语法,特别是关于B-树索引特性的章节和以下摘录

如果表有多列索引,则优化器可以使用索引的任何最左前缀来查找行。例如,如果您有一个三列索引on (col1,col2,col3),那么您已经在(col1)、(col1、col2)和(col1、col2、col3)上建立了索引搜索功能。 如果列没有构成索引的最左边前缀,则MySQL无法使用索引。假设这里显示了SELECT语句:

和

有时MySQL不使用索引,即使索引是可用的。出现这种情况的情况之一是,优化器估计使用索引将需要MySQL访问表中很大百分比的行。(在这种情况下,表扫描可能要快得多,因为它需要更少的搜索。)但是,如果这样的查询只使用限度检索部分行,那么MySQL无论如何都会使用索引,因为它可以更快地在结果中找到要返回的几行。

另外,您不需要引用数字数据类型,因此field_2 = 5 && status IN ( 1 , 2 )是有效的(事实上,由于引用整数数据类型而不是将它们指定为数字,我在过去遇到了一些奇怪的问题)。

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

https://stackoverflow.com/questions/17076619

复制
相关文章

相似问题

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