2013-03-13 95 views
1

我有它运行很慢(几乎50000条记录)以下查询如何优化这个慢速查询?

SELECT 
    news.id, 
    news.title, 
    DATE_FORMAT(news.date_online,'%d %m %Y')AS newsNL_Date 
    news_categories.parent_id 
FROM 
    news, 
    news_categories 
WHERE 
    DATE(news.date_online)=2013-02-25 
    AND news.category_id = news_categories.id 
    AND news.date_online < NOW() 
    AND news.activated ='t' 
ORDER BY 
    news.date_online DESC 

我有MySQL客户端版本5.0.96

当我运行EXPLAIN EXTENDED调用这个查询,这是结果:

 
id select_type table    type  possible_keys      key   key_len  ref    rows  Extra 
1  SIMPLE  news    ref  category_id,date_online,activated activated 1   const    43072 Using where; Using filesort 
1  SIMPLE  news_categories eq_ref PRIMARY,id       PRIMARY  4   news_category_id 1  

我有以下列的索引 news_id(主键) date_online 激活 美食gory_id

当我看看EXPLAIN EXTENDED结果时,我看到了USING_WHERE;使用FILESORT。我知道他们两人都不好,但我不知道如何解决这个问题。

回答

-1

您的查询获取数据特定日期,所以在这种情况下,你可以省略AND news.date_online < NOW()一部分(可能是查询优化器可以实现这个要求)。

在另一种情况下,如果您希望所有活动消息没有指定date_online,那么您也应该除去NOW()。问题是,你的查询不能被数据库缓存,因为它包含每个执行都不同的部分(NOW())。你可以通过在那里提供一个计算的常量来做到这一点如果您在比较过程中忽略了分钟部分,则可以将其缓存到最大值。 60秒。

接下来,您应该为您正在使用的列创建多列索引,因为我猜category_iddate_onlineactivated几乎用于每个查询。这会使插入速度稍慢,但从它看起来像(新闻应用程序)将有更多的读取比插入。

1

尝试为date_online(B型树)添加索引。另外我会尽量避免在close处使用NOW(),而是将其设置在一个变量中,然后使用该变量。

我想id字段是键,所以他们已经索引。

+0

谢谢,我已经得到了一个date_online的索引 – user1169366 2013-03-13 12:08:48

+0

date_online上的索引被忽略,因为您不是直接使用该列,而是对该列的值执行函数并比较结果 – Kickstart 2013-03-13 13:13:53

1

使用LEFT JOIN,看到了差距

SELECT 
    news.id, 
    news.title, 
    DATE_FORMAT(news.date_online,'%d %m %Y')AS newsNL_Date 
    news_categories.parent_id 
FROM 
    news 
LEFT JOIN news_categories ON news_categories.id = news.category_id 
WHERE 
    DATE(news.date_online)= '2013-02-25' 
    AND DATE(news.date_online) < DATE(NOW()) 
    AND news.activated ='t' 
ORDER BY 
    news.date_online DESC 
1

除了其他有价值的建议,你有DATE(news.date_online)= 2013-02-25。这似乎迫使MySQL将news.date_online转换为表格中每一行的不同格式。这将停止索引有用。

可能将其更改为news.date_online BETWEEN'2013-02-25 00:00:00'AND'2013-02-25 23:59:59'这应该(我认为)允许date_online上的索引要使用