0

我在 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 有数百万条记录的实际场景中,哪个更快?也有人可以解释它实际存储在数据库中的方式吗?

4

5 回答 5

0

第一次查询应该更快,它通过使用块过滤器来限制结果。

我会说:应用索引block以提高速度。

ALTER TABLE mytab 添加索引块索引(块);

查看 sqlfiddle 并比较执行计划:http ://sqlfiddle.com/#!9/317d6/1

于 2013-10-01T11:40:39.717 回答
0

请参阅@juergend 关于解释的评论。问题是“取决于”。如果任一字段上都没有索引,则数据库将进行全表扫描,因此没有真正的区别。如果 codeno 有 index 而 block 没有,那么这两个语句仍然大致等价,因为它在任何一种情况下都会使用 codeno 上的索引。如果两个字段上的索引如果数据库认为使用块索引进行首次访问更有利,则具有两个条件的字段可能会更快。但是解释应该向您展示数据库决定用于访问计划的内容。

于 2013-10-01T11:43:48.570 回答
0

我认为两者都需要相同的时间,因为两者的执行计划是相同的

在此处输入图像描述

  1. 选择数据

  2. 表扫描 100%

并查看执行计划详细信息

在此处输入图像描述

在此处输入图像描述

于 2013-10-01T11:38:11.740 回答
0

在没有看到执行计划的情况下,我猜第一个过滤器会减少设置第二个过滤器的记录数量,这使得第一个选项更快,特别是 like 运算符是一个字符串比较,这并不是真正有效作为数字或二进制比较。

要了解更多信息,您可以生成两个语句的执行计划并比较运行时间,请查看文档

于 2013-10-01T11:38:20.893 回答
0

如果表上没有任何索引,第一次查询将花费更多时间,这是因为无法从内存中获取任何内容,但您必须检查两个字段而不是一个字段。

但是当您可以添加自己的索引时,这种非规范化确实非常有用。您可以只添加(block)索引,以便在内存中完成相等性检查,并且第二个条件的数据将从磁盘中获取,但仅适用于与第一个条件匹配的那些行。当大多数匹配第一个条件的行也匹配第二个条件时,这尤其有用。

另一方面,您可以添加(codeno(1))索引,该索引将用于前缀检查codeno like 'b%'(确保在索引中指定足够长的前缀),这几乎需要相同的时间。在这种情况下,条件block='b'不是必需的,甚至是阻碍的。

于 2013-10-01T16:12:03.677 回答