2012-03-20 91 views
0

比方说,我有以下SQL查询使查询更加高效

SELECT id, name, title, description, time 
    FROM entity 
    WHERE UNIXTIMESTAMP(CONCAT(date_end, time_end)) > UNIXTIMESTAMP(NOW()) 
    AND UNIXTIMESTAMP(CONCAT(next_date, next_time)) < UNIXTIMESTAMP(NOW()) 

我一直在寻找到的意见等方式,使该查询更有效。问题是如果我有超过10,000个实体要处理;那么查询将需要很长时间。

MySQL提供了哪些工具来提高查询的效率?谢谢!

+0

您是否考虑过重构数据库表并使用'DATETIME'字段类型?或者甚至更好,'BIGINT'来存储原始的Unix时间戳? – 2012-03-20 23:41:00

+0

“date_end”,“time_end”等的数据类型是什么? – 2012-03-20 23:41:44

+0

什么专栏是您的索引? – Ben 2012-03-20 23:43:00

回答

4

如果您只是使用常规技术,那么就已经有了关于该主题的SO问题,更不用说关于optimization的MySQL手册部分了。

如果您在查询的特定建议之后,请注意,如果列通过函数传递,则MySQL不能应用索引。您需要摆脱围绕* _end和next_ *列的UNIXTIMESTAMPCONCAT调用。一种方法是更改​​表格模式:将列组合成DATETIMETIMESTAMP类型的“结束”和“下一个”列。另一种方法是将当前时间分隔成日期和时间,并将其与单独的列进行比较。

1

请看explain - 它会告诉你发动机盖下发生了什么。

1

也许看看使用日期时间字段而不是两个字段 - 这将删除查询中不必要的数据转换。

SELECT id, name, title, description, time 
FROM entity 
WHERE NOW() BETWEEN (date_time_end AND date_time_next); 

不要以为你会比没有根据日期划分表格的情况好得多。

0

我认为这应该会提高查询性能而不改变数据库模式。

SELECT id, name, title, description, time FROM entity 
WHERE NOW() BETWEEN ADDTIME(next_date, next_time) AND ADDTIME(date_end, time_end) 

其实BETWEEN将与>=<=比较。如果你不希望它是这样的,那么保持与><的比较,而不是使用BETWEEN

2

您的查询将被罚款,只有10K的记录过程,但是这应该是更有效,因为它不涉及任何类型的转换 -

SELECT id, name, title, description, time 
FROM entity 
WHERE (date_end > CURRENT_DATE OR (date_end = CURRENT_DATE AND time_end >= CURRENT_TIME)) 
AND (next_date < CURRENT_DATE OR (next_date = CURRENT_DATE AND next_time <= CURRENT_TIME)) 

上(NEXT_DATE,DATE_END)复合指数也应该有帮助性能,但如果您使用EXPLAIN来检查执行计划,它应该帮助您决定最有效的索引。您应该检查(date_end,next_date)上的索引。不知道更多关于数据分布的信息,不可能说哪一个最能提供帮助。

+0

所以我做了你所设想的。我添加了索引(next_date,date_end),但由于某种原因,当我对您提供的查询调用EXPLAIN时,它并未使用我创建的索引。 ..? – Jasmine 2012-03-21 00:11:27

+0

您是否尝试过使用索引?您可以尝试使用[FORCE INDEX](http://dev.mysql.com/doc/refman/5.1/en/index-hints.html)尝试索引来查看它们对执行计划的影响。 – nnichols 2012-03-21 00:22:54