【问题标题】:Faster select query for multiple primary key多个主键的更快选择查询
【发布时间】:2018-10-12 12:49:23
【问题描述】:

在测试我的简单邮件 MySQL 数据库时,我发现了一个奇怪的行为,很高兴知道原因。

我的“邮件”表有两个主键:

idx : INT(Auto-Increment)
uid : VARCHAR(50)

还有一些其他的虚拟列,如 createdTime、info 等。

然后,我用 200,000 个虚拟数据填充了我的表,并用一个简单的搜索查询进行了测试:

SELECT * FROM mail WHERE uid='RANDOMGENERATEDUID';

执行此查询大约需要 0.235 秒,从工作台的表格说明中我发现此查询执行全表扫描并且不使用任何键。

我很好奇如果我强制使用 'idx' 列进行 SELECT 查询会发生什么,所以,我测试了另一个查询,结果相同:

SELECT * FROM mail
WHERE idx IN (SELECT idx FROM foodwagondb.mail WHERE uid='RANDOMGENERATEDUID');

但令我惊讶的是,这个查询执行得更快,执行时间为 0.078 秒!

我的眼睛后面发生了什么?我很高兴知道为什么会这样!

【问题讨论】:

  • 一个原因可能是在第二个子查询中您只选择了idx,它可以直接从索引中检索,而无需访问表本身。 MySql 可能会决定,当它还需要选择其他字段时(*),使用索引变得不那么有趣,而“只”做表访问更有趣。这个决定可能取决于几个我不知道的因素。但以上可能是一个元素。
  • 这很有趣...由于第二个查询的性能要好得多,我宁愿选择这个。感谢您的回复!

标签: mysql sql database select


【解决方案1】:

你应该避免使用IN 子句,而使用INNER JOIN

SELECT m1.* FROM mail m1
INNER JOIN foodwagondb.mail m2 ON m2.idx = m1.idx 
WHERE idx m2.uid='RANDOMGENERATEDUID';

IN 子句等效于 OR 条件,这意味着对每个值重复相关查询.. 内连接仅执行查询并匹配结果值。

无论如何,您都可以使用适当的 uid 复合索引来改进查询

create index my_index on mail (uid, idx)

【讨论】:

  • 感谢您提供有关 IN 子句的信息!是的,复合索引大大加快了执行时间,对此一无所知。认为只设置主键就足够了,但不是:P
【解决方案2】:

在您的第一个查询中,您根据 varchar 字段 (uid) 搜索每一行。 在第二个查询中,mysql 根据索引字段 (idx) 预过滤行,然后在该子集中搜索文本字符串。对于较小的表,您不会看到差异,但对于较大的表,它会影响性能。 @scaisEdge 是对的,INNER JOIN 规则!

【讨论】:

    猜你喜欢
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多