哪个索引会加快查询速度?

时间:2017-04-22 10:34:55

标签: mysql sql database indexing

在3.5亿条记录表中,结构为:

CREATE TABLE `table` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `job_id` int(10) unsigned NOT NULL,
    `lock` mediumint(6) unsigned DEFAULT '0',
    `time` timestamp NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `job_id` (`job_id`),
    KEY `lock` (`lock`),
    KEY `time` (`time`)
) ENGINE=MyISAM;

我应该创建什么索引来加速查询:

UPDATE `table` SET `lock` = 1 WHERE `lock` = 0 ORDER BY `time` ASC LIMIT 500;

2 个答案:

答案 0 :(得分:1)

lock被声明为NULLable。这是否意味着该值通常为NULL?如果是这样,那么MyISAM(不是InnoDB)中存在一个令人讨厌的问题,可能导致额外的500个碎片命中。

当更新MyISAM行时,它变得更长,那么该行将不再适合它。 (现在我的详细知识变得模糊。)新行将放在其他地方和/或它将分成两部分,部分之间有链接。这意味着在两个地方写作。

正如Gordon指出的那样,对你的案例中任何索引列lock的任何更改都涉及一个代价高昂的索引更新 - 从索引的BTree中的一个地方删除一行'并在另一个地方添加一行

lock只有0或1的值吗?然后使用TINYINT(1个字节),而不是MEDIUMINT(3个字节)。

您应该检查MAX(id)。如果它是干净的,id的最大值将是大约350M(不太接近4B的限制)。但如果有任何流失,可能会更接近极限。

我也主张转换到InnoDB。但是,您的10GB(数据+索引)将在转换中增长到20-30GB。

你是“锁定最老的解锁”东西吗?然后你会选择看看锁定了什么吗?

如果这个太慢,请不要一次做500,选择较低的数字。

使用InnoDB,你能避免锁定吗? 也许事务锁定就足够了?

我认为我们需要看到其他环境 - 其他表格,工作“流程”等。我们可能会提出其他建议。

我为INDEX(lock, time)提出动议。但是,在执行此操作时,DROPlock上的索引是多余的。

转换为InnoDB时,请在同一 ALTER中对所有索引进行更改。这比单独的传球跑得快。

答案 1 :(得分:0)

对于此查询:

UPDATE `table`
    SET `lock` = 1
    WHERE `lock` = 0
    ORDER BY `time` ASC
    LIMIT 500;

最佳指数为table(lock, time)。但请注意,更新还需要更新索引,因此您应该测试它在实践中的效果。不要将其作为聚集索引。这只会减慢这个过程。