开发者

Optimize Mysql Query (group and order by -> Using index; Using temporary; Using filesort)

开发者 https://www.devze.com 2023-01-22 16:27 出处:网络
Here`s my SHOW CREATE TABLE tbl: CREATE TABLE IF NOT EXISTS `msc_pagestats` ( `id` int(10) unsigned NOT NULL auto_increment,

Here`s my SHOW CREATE TABLE tbl:

CREATE TABLE IF NOT EXISTS `msc_pagestats` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `domain` varchar(250) NOT NULL,
  `file` varchar(200) NOT NULL,
  `simbol` varchar(100) NOT NULL,
  `request_time` timestamp NULL default CURRENT_TIMESTAMP,
  `querystring` mediumtext NOT NULL,
  `host` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `myindex开发者_运维百科` (`simbol`,`request_time`,`file`,`domain`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin2 AUTO_INCREMENT=248008 ;

So basically this table keeps track on what simbols have been most accesed, most viewed, most searched within the site based on a query string.

My query is:

SELECT  `simbol`, count(*) AS requests
 FROM msc_pagestats 
 WHERE 1=1 AND request_time > '20100504000000' 
        AND simbol NOT LIKE ''
 GROUP BY `simbol`
        ORDER BY requests DESC
 LIMIT 0, 15;

This query EXPLAINED:

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra

1  SIMPLE  msc_pagestats  index  NULL  myindex  561  NULL  24961  Using where; Using index; Using temporary; Using filesort

So the query tryes to get the most accesed symbols in the latest hour or today.

Here's what I've tried doing in order to get rid of using temporary and using filesort:

  1. Adding an ID as primary key and using COUNT(id) AS requests instead of the COUNT(*) AS requests;
  2. Removing the where 1=1 and simbol not like='', it dosen`t prove a big difference though;
  3. Adding a multiple index instead of the reqular index, previously there were indexes on each column ex (KEY(request_time), KEY(file), KEY(domain), KEY(simbol)).

I'm not that good on optimization, so I`ve runed out of options.

Here's a dump of my 'mysq_slow_query' file:

Query_time: 3 Lock_time: 0 Rows_sent: 15 Rows_examined: 220297

use kmarket;
SELECT  `simbol`, count(*) AS requests
 FROM msc_pagestats 
 WHERE 1=1 AND request_time > '20100504000000' 
        AND simbol NOT LIKE ''
        GROUP BY `simbol`
 ORDER BY requests DESC
 LIMIT 0, 15;

Any help would be appreciated, thanks :)


Not much point in adding an index to a field calculated at run time, it would still need to be sorted/indexed on each run.

An index on (request_time,simbol) may allow the optimiser to exclude a lot of rows more quickly and also reduce the key length.

0

精彩评论

暂无评论...
验证码 换一张
取 消