【发布时间】:2009-12-30 14:56:44
【问题描述】:
给定下表:
desc exchange_rates;
+------------------+----------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| time | datetime | NO | MUL | NULL | |
| base_currency | varchar(3) | NO | MUL | NULL | |
| counter_currency | varchar(3) | NO | MUL | NULL | |
| rate | decimal(32,16) | NO | | NULL | |
+------------------+----------------+------+-----+---------+----------------+
我在 time、base_currency 和 counter_currency 上添加了索引,并在 (time、base_currency、counter_currency) 上添加了一个复合索引,但是当我执行 @987654326 时,我发现性能差异很大@ 使用<= 反对使用<。
第一个SELECT是:
ExchangeRate Load (95.5ms)
SELECT * FROM `exchange_rates` WHERE (time <= '2009-12-30 14:42:02' and base_currency = 'GBP' and counter_currency = 'USD') LIMIT 1
如您所见,这需要 95 毫秒。
如果我更改查询以便使用< 而不是<= 比较时间,我会看到:
ExchangeRate Load (0.8ms)
SELECT * FROM `exchange_rates` WHERE (time < '2009-12-30 14:42:02' and base_currency = 'GBP' and counter_currency = 'USD') LIMIT 1
现在只需要不到 1 毫秒,这对我来说是正确的。这种行为有合理的解释吗?
EXPLAIN 的输出提供了更多详细信息,但我不能 100% 确定如何解释:
-- Output from the first, slow, select
SIMPLE | 5,5 | exchange_rates | 1 | index_exchange_rates_on_time,index_exchange_rates_on_base_currency,index_exchange_rates_on_counter_currency,time_and_currency | index_merge | Using intersect(index_exchange_rates_on_counter_currency,index_exchange_rates_on_base_currency); Using where | 813 | | index_exchange_rates_on_counter_currency,index_exchange_rates_on_base_currency
-- Output from the second, fast, select
SIMPLE | 5 | exchange_rates | 1 | index_exchange_rates_on_time,index_exchange_rates_on_base_currency,index_exchange_rates_on_counter_currency,time_and_currency | ref | Using where | 4988 | const | index_exchange_rates_on_counter_currency
(注意:我通过ActiveRecord(在 Rails 应用程序中)生成这些查询,但这些最终是正在执行的查询)
【问题讨论】:
-
PROCEDURE ANALYSE() 说什么? dev.mysql.com/doc/refman/5.0/en/procedure-analyse.html
标签: mysql ruby-on-rails activerecord