Mysql 使用<;=反对使用<;在DATETIME列上
鉴于下表:Mysql 使用<;=反对使用<;在DATETIME列上,mysql,ruby-on-rails,activerecord,Mysql,Ruby On Rails,Activerecord,鉴于下表: desc exchange_rates; +------------------+----------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | time | datetime | NO | MUL | NULL |
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 | |
+------------------+----------------+------+-----+---------+----------------+
我在
时间
、基本货币
和反货币
上添加了索引,并在(时间、基本货币、反货币)上添加了一个综合索引,但在第一种情况下,当我使用执行选择
时,我看到了巨大的性能差异,MySQL
尝试合并所有索引的结果。它从两个索引中获取所有记录,并根据行指针的值(在MyISAM
中的表偏移量,InnoDB
中的PRIMARY KEY
)连接它们
在第二种情况下,它只使用一个索引,考虑到限制1
,这是最佳决策
您需要在(基本货币、计数器货币、时间)
(按此顺序)上创建一个复合索引,以便此查询尽可能快地工作
引擎将使用索引在前导列(基本货币、计数器货币)
上进行过滤,并在尾随列(时间)
上进行排序
您似乎还想在查询中添加类似于orderbytime DESC
的内容,以获取最后一次汇率
一般来说,没有按
排序的任何限额都应该会敲响警钟。您好,谢谢,但我实际上已经在(时间、基准货币、计数器货币)上添加了一个综合指数。@Olly
:列的顺序错误。顺序很重要。剩下的唯一一点是,为什么查询计划者在@Michael
时输出不同的计划:我自己从来没有见过它(现在也不能复制它),但似乎大多数记录都正好在作为参数传递的时间戳内,@OP
刚好达到了临界点,MySQL
更喜欢一个计划而不是另一个计划。不管怎样,我们需要访问实际数据才能准确地判断。关于顺序,我认为复合索引必须反映WHERE子句中字段出现的顺序?在我的例子中,时间先到,然后是基本货币,然后是反货币,因此我使用(时间、基本货币、反货币)创建了索引。这不对吗?过程分析()说了什么?
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
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
-- 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