mysql 按主键选择顺序。表现

1 mysql indexing performance

我有一个类似这样的表“tbl”: ID bigint(20) - Primary key, autoincrement field1 field2 field3

该表有 600k 多行。

  1. 查询:SELECT * from tblORDER by ID LIMIT 600000, 1 需要 1.68 秒
  2. 查询:SELECT ID, field1 from tblORDER by ID LIMIT 600000, 1 需要 1.69 秒
  3. 查询:SELECT ID from tblORDER by ID LIMIT 600000, 1 需要 0.16 秒
  4. 查询:选择*来自tbl WHERE ID = xxx 需要 0.005 秒

这些查询在 phpmyadmin 中进行测试。

结果是查询3和查询4一起返回必要的数据。查询 1 执行相同的工作,但速度慢得多......

这看起来不适合我。有人可以提供任何建议吗?

PS 我很抱歉格式化..我是这个网站的新手。

新测试:

Q5:创建临时表 tmptable AS (SELECT ID FROM tblWHERE ID LIMIT 600030, 30); 选择*从tbl WHERE ID IN (SELECT ID FROM tmptable); 需要 0.38 秒

我还是不明白这怎么可能。我重新创建了所有索引..我还能用该表做什么?手动删除并重新填充?:)

Kev*_*vin 5

查询 1 查看表的主键索引,找到正确的 600,000 个 id 及其在表中的相应位置,然后转到表并从这 600k 位置获取所有内容。

查询 2 查看表的主键索引,找到正确的 600k id 及其在表中的相应位置,然后转到表并从这 600k 行中获取所需的字段子集。

查询 3 查看表的主键索引,找到正确的 600k id,然后返回它们。根本不需要看表。

查询 4 ​​查看表的主键索引,找到请求的单个条目,转到表,读取该单个条目,然后返回它。

从时间上来说,让我们向后构建:

(Q4) 表索引允许在 O(log n) 时间内查找键 (id),这意味着每次表大小加倍时,只需要一个额外的步骤即可在索引*中查找键。如果您有 100 万行,那么只需大约 20 步即可找到它。十亿行?30 步。索引条目包含有关在表中何处查找该行数据的数据,因此 MySQL 会跳转到表中的该位置并读取该行。为此报告的时间几乎完全是开销。

(Q3)正如我提到的,表索引非常快;该查询找到第一个条目,然后遍历树,直到它具有请求的行数。我确信我可以计算出所需的精确步数,但最多我们会说 20 步 x 600k 行 = 12M 步;由于它遍历一棵树,因此可能更像 1M 步,但精确的数字很大程度上无关紧要。这里要认识到的最重要的事情是,一旦 MySQL 遍历索引以提取它需要的 id,它就会拥有您所要求的一切。没必要去看表。这一报告的时间本质上是 MySQL 遍历索引所花费的时间。

(Q2) 这从与查询 3 所讨论的相同的树遍历开始,但是在提取所需的 ID 时,MySQL 还会提取它们在表文件中的位置。然后它必须转到表文件(可能已经缓存/mmap存储在内存中),对于它提取的每个条目,寻找表中的正确位置并从这些行中获取请求的字段。此查询报告的时间是遍历索引所需的时间(如 Q3 中所示)加上访问索引中指定的每一行的时间。

(Q1) 当指定所有字段时,这与 Q2 相同。由于时间与第二季度基本相同,我们可以看到,从数据库中提取更多字段并没有真正花费更多的时间,任何时候通过爬行索引和查找行都显得相形见绌。

*:大多数数据库使用索引数据结构( MySQL 的B 树),其日志基数远高于 2,这意味着不是每次表翻倍时都需要执行额外的步骤,而更像是每次表大小增加时执行额外的步骤上升数百至数千倍。这意味着,它更像是 2-5 个步骤,而不是我在示例中所述的 20-30 个步骤。