SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 21.11.2008 14:10:20

Mikasto
Завсегдатай
Зарегистрирован: 25.09.2007
Сообщений: 35

Можно ли оптимизировать запрос?

Таблицы:


CREATE TABLE `stat_sessions` (
  `id` bigint(20) unsigned NOT NULL,
  `id_site` bigint(20) unsigned NOT NULL,
  `id_ref` bigint(20) unsigned NOT NULL,
  `id_engine` bigint(20) unsigned NOT NULL,
  `id_phrase` bigint(20) unsigned NOT NULL,
  `dt_start` datetime NOT NULL COMMENT,
  `dt_end` datetime NOT NULL COMMENT,
  `date` date NOT NULL COMMENT,
  `duration` int(11) unsigned NOT NULL default '0',
  `time_group` tinyint(1) NOT NULL default '1',
  `pages_count` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `id_site` (`id_site`,`date`,`id`),
  KEY `id_site3` (`id_site`,`date`,`pages_count`),
  KEY `id_site2` (`id_site`,`date`,`time_group`,`id_engine`),
  KEY `id_site4` (`id_site`,`date`,`id_phrase`,`time_group`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `stat_phrases` (
  `id` bigint(20) unsigned NOT NULL COMMENT 'ПК',
  `phrase` varchar(255) default NULL COMMENT 'Текст фразы',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
 


Производим запрос:

SELECT COUNT(*) cnt
FROM stat_sessions ss
    JOIN stat_phrases sh ON ss.id_phrase = sh.id
WHERE id_site = 3859145633108167829
    AND ss.`date` IN ('20081113')
    AND sh.`phrase` = 'московские окна'
 


EXPLAIN:
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    ss    ref    id_site,id_site3,id_site2,id_site4    id_site4    11    const,const    3232    Using index
1    SIMPLE    sh    eq_ref    PRIMARY    PRIMARY    8    test.ss.id_phrase    1    Using where

Результат:
cnt 83
(0.48 sek)

Вопросы:
1. Почему при использовании индекса запрос такой медленный?
2. Почему EXPLAIN выдает 3232 вместо цифры приближенной к 83?
3. Почему при повторном выполнении запроса, или при изменении  AND sh.`phrase` = <другое значение> время 0.02 сек ?
4. Почему при выполнении с AND ss.`date` IN (<другая дата>) время сокращается до 0.11 сек а не до 0.02?
5. Как оптимизировать запрос и/или таблицы и/или сервер ?

Неактивен

 

#2 21.11.2008 14:32:49

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Можно ли оптимизировать запрос?

1. А почему Вы считаете, что 0.5 секунды - это медленно?
2. Потому что Выбирается 3232 строки из ss (по id_site и `DATE`) и к ним выбирается по 1 строке из sh
3. Потому что используется query cache
4. Потому что за другую дату строк меньше
5. Можете, например сделать отдельную статистическую табличку с количествами.

P.S.
Если названия табличек правильные, то вторая табличка по сути является индексатором "фраза в id"
и фраза в ней должна быть уникальной. Тогда логичным было бы в ней иметь уникальный ключик
на фразе. Тогда запрос будет выполняться "в обратную сторону", т.е. сначала выбираться id из sh,
а потом данные из ss (понадобится ключик на (id_phrase, DATE, id_site)).

Неактивен

 

#3 21.11.2008 14:53:45

Mikasto
Завсегдатай
Зарегистрирован: 25.09.2007
Сообщений: 35

Re: Можно ли оптимизировать запрос?

paulus написал:

1. А почему Вы считаете, что 0.5 секунды - это медленно?

Потому что 100  таких запросов в секунду повесят сервер.

P.S. помог - и как я сам об этом не подумал. smile
Спасибо.
в итоге запрос:
SELECT COUNT(*) cnt
FROM stat_sessions ss
WHERE id_site = 3859145633108167829
    AND ss.`date` IN ('20081112')                               
    AND ss.`id_phrase` = 1184296430239181593

и выполняется безумно быстро - что и требовалось. Я рад.

Неактивен

 

#4 21.11.2008 14:59:38

Mikasto
Завсегдатай
Зарегистрирован: 25.09.2007
Сообщений: 35

Re: Можно ли оптимизировать запрос?

А еще подвох был а том, что:

SELECT *
FROM `stat_phrases` s
WHERE s.`phrase` = 'московские окна'


Выдает много строк вместо 1й (придется приводить все к нижнему регистру):
id                               phrase
1184296430239181593    московские окна
1921506984546157405    Московские окна
313527517360681430    МОСКОВСКИЕ ОКНА
4113086964125427273    Московские Окна
1658956355332919903    Московские ОКНА
4216182914979148941    МОсковские окна
2910815411339435350    мОсковские окна
4969293543036981317    московские Окна
1709261834205483246    мОСКОВСКИЕ ОКНА

Неактивен

 

#5 21.11.2008 20:38:07

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Можно ли оптимизировать запрос?

Если уже существующие данные - то да, а вообще хорошо бы иметь ci-сопоставление, тогда
оно будет не чувствительно к регистру.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson