MySQL 如果记录存在,按日期搜索的最快方法
MySQL fastest way to search by DATE if a record exist
我找到了很多方法来按 DATE
搜索 mysql 记录
方法一:
SELECT id FROM table WHERE datetime LIKE '2015-01-01%' LIMIT 1
方法二(同方法一+ORDER BY):
SELECT id FROM table WHERE datetime LIKE '2015-01-01%' ORDER BY datetime DESC LIMIT 1
方法三:
SELECT id FROM table WHERE datetime BETWEEN '2015-01-01' AND '2015-01-01 23:59:59' LIMIT 1
方法四:
SELECT id FROM table WHERE DATE_FORMAT( datetime, '%y.%m.%d' ) = DATE_FORMAT( '2015-01-01', '%y.%m.%d' )
方法五(我认为是最慢的):
SELECT id FROM table WHERE DATE(`datetime`) = '2015-01-01' LIMIT 1
最快的是什么?
在我的例子中,table 有 100 万行,要搜索的日期始终是最近的。
你提到的最快的方法是
SELECT id
FROM table
WHERE datetime BETWEEN '2015-01-01' AND '2015-01-01 23:59:59'
LIMIT 1
当您在 datetime
列上创建索引时,这会变得很快。可以随机访问索引以找到第一个匹配行,然后扫描直到最后一个匹配行。所以没有必要阅读整个 table,甚至没有必要阅读整个索引。而且,当您使用 LIMIT 1
时,它只会读取单行。非常快,即使在巨大的 table.
上也是如此
您的其他搜索方式对每一行应用一个函数:
datetime LIKE '2011-01-01%'
将 datetime
转换为每一行的字符串。
- 方法 3、4 和 5 都对每一行的内容使用
DATE()
等显式函数。
使用这些函数可以击败使用索引来查找数据。
专业提示:不要将 BETWEEN
用于日期运算,因为它无法很好地处理结束条件。而是使用
WHERE datetime >= '2015-01-01'
AND datetime < '2015-01-02'
这与 BETWEEN
的表现一样好,并且让您不必将 2015-01-01
的最后时刻明确写为 23:59:59
。无论如何,这对于更高精度的时间戳是不正确的。
假设日期时间列上有索引,最快的方法是方法 3 的变体,除了 两者 范围值都是日期时间文字:
SELECT id FROM table
WHERE datetime BETWEEN '2015-01-01 00:00:00' AND '2015-01-01 23:59:59'
LIMIT 1
使用与列相同类型的文字意味着不会对列进行任何强制转换来执行比较,从而为在列上使用索引提供了最佳机会。我在生产中使用它效果很好。
我找到了很多方法来按 DATE
搜索 mysql 记录方法一:
SELECT id FROM table WHERE datetime LIKE '2015-01-01%' LIMIT 1
方法二(同方法一+ORDER BY):
SELECT id FROM table WHERE datetime LIKE '2015-01-01%' ORDER BY datetime DESC LIMIT 1
方法三:
SELECT id FROM table WHERE datetime BETWEEN '2015-01-01' AND '2015-01-01 23:59:59' LIMIT 1
方法四:
SELECT id FROM table WHERE DATE_FORMAT( datetime, '%y.%m.%d' ) = DATE_FORMAT( '2015-01-01', '%y.%m.%d' )
方法五(我认为是最慢的):
SELECT id FROM table WHERE DATE(`datetime`) = '2015-01-01' LIMIT 1
最快的是什么?
在我的例子中,table 有 100 万行,要搜索的日期始终是最近的。
你提到的最快的方法是
SELECT id
FROM table
WHERE datetime BETWEEN '2015-01-01' AND '2015-01-01 23:59:59'
LIMIT 1
当您在 datetime
列上创建索引时,这会变得很快。可以随机访问索引以找到第一个匹配行,然后扫描直到最后一个匹配行。所以没有必要阅读整个 table,甚至没有必要阅读整个索引。而且,当您使用 LIMIT 1
时,它只会读取单行。非常快,即使在巨大的 table.
您的其他搜索方式对每一行应用一个函数:
datetime LIKE '2011-01-01%'
将datetime
转换为每一行的字符串。- 方法 3、4 和 5 都对每一行的内容使用
DATE()
等显式函数。
使用这些函数可以击败使用索引来查找数据。
专业提示:不要将 BETWEEN
用于日期运算,因为它无法很好地处理结束条件。而是使用
WHERE datetime >= '2015-01-01'
AND datetime < '2015-01-02'
这与 BETWEEN
的表现一样好,并且让您不必将 2015-01-01
的最后时刻明确写为 23:59:59
。无论如何,这对于更高精度的时间戳是不正确的。
假设日期时间列上有索引,最快的方法是方法 3 的变体,除了 两者 范围值都是日期时间文字:
SELECT id FROM table
WHERE datetime BETWEEN '2015-01-01 00:00:00' AND '2015-01-01 23:59:59'
LIMIT 1
使用与列相同类型的文字意味着不会对列进行任何强制转换来执行比较,从而为在列上使用索引提供了最佳机会。我在生产中使用它效果很好。