我在MySQL数据库中有一个表:
CodeNo Block
a1 a
a2 a
b1 b
b2 b
c1 c
c2 c
我可以使用以下两种选择之一进行查询:
select codeno from mytab where block='b' and codeno like 'b%'
替代地
select codeno from mytab where codeno like 'b%'
当mytab中有数百万条记录时,哪一个在实际场景中更快?也有人能解释它实际存储在数据库中的方式吗?
答案 0 :(得分:0)
我认为两者都需要相同的时间,因为两者的执行计划是相同的
选择数据
表格扫描100%
并查看执行计划详情
答案 1 :(得分:0)
如果没有看到执行计划,我猜第一个过滤器会减少设置第二个过滤器的记录数量,这使得第一个选项更快,特别是类似运算符是一个字符串比较,这不是真的和数字或二元比较一样有效。
要了解更多相关信息,您可以生成两个语句的执行计划并比较运行时间,看看documentation
答案 2 :(得分:0)
第一个查询应该更快,它通过使用块过滤器来限制结果。
我会说:在block
上应用索引来提高速度。
ALTER TABLE mytab ADD INDEX blockindex(block);
请参阅sqlfiddle并比较执行计划:http://sqlfiddle.com/#!9/317d6/1
答案 3 :(得分:0)
请参阅@juergend关于解释的评论。问题是“它取决于”。如果在任一字段上都没有索引,则DB将执行全表扫描,因此没有真正的区别。如果codeno有索引而block没有,那么这两个语句仍然大致相同,因为在任何一种情况下它都会使用codeno上的索引。如果两个字段的索引,如果DB确定使用块索引进行首次访问更有利,则具有两个条件的索引可能更快。但是解释应该向您展示数据库决定用于访问计划的内容。
答案 4 :(得分:0)
如果表上没有任何索引,第一个查询将花费更多时间,这是因为没有任何东西可以从内存中获取,但你必须检查两个字段而不是一个。
但是当你可以添加自己的索引时,这种非规范化确实非常有用。您可以只添加(block)
索引,以便在内存中完成相等性检查,第二个条件的数据将从磁盘中获取,但仅适用于与第一个条件匹配的行。当与第一个条件匹配的大多数行与第二个条件匹配时,这尤其有用。
从另一方面,您可以添加(codeno(1))
索引,索引将用于codeno like 'b%'
之类的前缀检查(请务必在索引中指定足够长的前缀),这样几乎在同一时间。在这种情况下,条件block='b'
不是必需的,甚至是阻碍的。