我有一张大型MyISAM表。它接近100万行。它基本上是一个项目列表和一些有关它们的信息。
有两个指数:
我运行两个查询:
SELECT * FROM table WHERE date = '2011-02-01' AND col < 5 LIMIT 10
SELECT * FROM table WHERE date < '2011-02-01' AND col < 5 LIMIT 10
第一个在~0.0005秒内完成,第二个在~0.05秒内完成。这是100倍的差异。我期望这两者以大致相同的速度运行是不对的?我不能很好地理解这些指数。如何加快第二次查询?
答案 0 :(得分:2)
无论Mysql如何,它都归结为基本的算法理论。
大型集合上的大于和小于操作比身份操作慢。 对于大数据集,用于确定小于或大于的自然平衡树(二进制或n树)的理想数据结构。 在自平衡树上,找到所有更小/更大的最坏情况是 log n 。
身份查找的理想数据结构是哈希表。哈希表的性能通常是 O(1),也就是固定时间。然而,哈希表不会更好/更少。
通常,一个平衡良好的树只比一个哈希表(这就是Haskell使用树用于哈希表的方式)的表现稍差。
因此无论Mysql做什么都不会让人感到惊讶&lt;,&gt;慢于=
以下旧答案:
因为第一个就像Hashtable查找一样,因为它的'='(特别是如果你的索引是一个哈希表),它会比第二个更快,它可能更像树索引一样。
由于MySql允许配置索引格式,您可以尝试更改它,但我相信第一个将始终比第二个运行得更快。
答案 1 :(得分:2)
我假设你在日期栏上有一个索引。 第一个查询使用索引,第二个查询可能执行线性扫描(至少部分数据)。直接提取总是比线性扫描更快。
答案 2 :(得分:2)
MySQL默认将其索引存储在BTREE中。一般没有哈希。
性能差异的简短答案是&lt; form评估更多节点,然后是= form。
你在那里的索引(日期,col)将值大致存储为电话簿:
2011-01-01, col=1, row_ptr
2011-01-01, col=2, row_ptr
2011-01-01, col=3, row_ptr
etc...
2011-02-01, col=1, row_ptr
2011-02-01, col=2, row_ptr
2011-02-01, col=3, row_ptr
etc...
2011-02-02, col=1, row_ptr
2011-02-02, col=2, row_ptr
etc...
...在大小为B的升序排序树节点中(2011-01-01,col = 1)&lt; (2011-01-01,col = 2)&lt; (2011-01-02,col = 1)。
你的问题基本上是要求区别:
很明显为什么#1比#2快得多。
还考虑了内存/磁盘传输效率和堆分配(= WAY减少传输然后&lt;),这占用了不可忽视的时间,但在很大程度上取决于数据的分布和特定的位置。 2011-02-01,col = min(col)关键记录。
答案 3 :(得分:1)
第一个执行搜索数据,其中第二个用于扫描。扫描总是比寻找更昂贵因此时差。
就像这样,扫描意味着贯穿本书的所有页面,其中搜索直接跳转到页码。
希望这可能会有所帮助。