如何针对大型数据库优化MySQL查询

时间:2013-11-27 12:19:02

标签: mysql sql

我最近注意到一个严重的问题,当我的数据库增加到超过620000条记录时。以下查询:

SELECT *,UNIX_TIMESTAMP(`time`) AS `time` FROM `log` WHERE (`projectname`="test" OR `projectname` IS NULL)  ORDER BY `time` DESC LIMIT 0, 20

在本地数据库上的执行时间约为2.5秒。我想知道如何加快速度呢?

EXPLAIN命令产生以下输出:

ID: 1
select type: SIMPLE
TABLE: log
type: ref_or_null
possible_keys: projectname
key: projectname
key_len: 387
ref: const
rows: 310661
Extra: Using where; using filesort

我在projectname,time columns上设置了索引。

任何帮助?

编辑:感谢ypercube响应,我能够减少查询执行时间。但是当我只向WHERE子句添加另一个条件(AND severity =“changes”)时,它再次持续2秒。将所有可能的“WHERE”列包含在我的合并索引中是否是一个很好的解决方案?

ID: 1 
select type: SIMPLE 
TABLE: log 
type: ref_or_null 
possible_keys: projectname 
key: projectname 
key_len: 419 
ref: const, const 
rows: 315554 
Extra: Using where; using filesort

表格结构:

   CREATE TABLE `log` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `projectname` VARCHAR(128) DEFAULT NULL,
  `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `master` VARCHAR(128) NOT NULL,
  `itemName` VARCHAR(128) NOT NULL,
  `severity` VARCHAR(10) NOT NULL DEFAULT 'info',
  `message` VARCHAR(255) NOT NULL,
  `more` TEXT NOT NULL,
  PRIMARY KEY (`id`),
  KEY `projectname` (`severity`,`projectname`,`time`)
) ENGINE=INNODB AUTO_INCREMENT=621691 DEFAULT CHARSET=utf8

1 个答案:

答案 0 :(得分:1)

(projectname, time)上添加索引:

ALTER TABLE log
  ADD INDEX projectname_time_IX            -- choose a name for the index
    (projectname, time) ;

然后使用ORDER BY

的原始列
SELECT *, UNIX_TIMESTAMP(time) AS unix_time 
FROM log 
WHERE (projectname = 'test' OR projectname IS NULL)  
ORDER BY time DESC 
LIMIT 0, 20 ;

或此变体 - 以确保有效使用索引:

  ( SELECT *, UNIX_TIMESTAMP(time) AS unix_time 
    FROM log 
    WHERE projectname = 'test'
    ORDER BY time DESC 
    LIMIT 20 
  )
  UNION ALL 
  ( SELECT *, UNIX_TIMESTAMP(time) AS unix_time 
    FROM log 
    WHERE projectname IS NULL
    ORDER BY time DESC 
    LIMIT 20 
  ) 
  ORDER BY time DESC
  LIMIT 20 ;
相关问题