SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 30.12.2009 16:35:53

pt81
Участник
Зарегистрирован: 21.12.2009
Сообщений: 5

Медленный запрос к одной таблице.

Нужно выбирать данные из некоторой таблицы с разными видами сортировок, привожу примеры запросов:

C cортировкой по дате:

select sql_calc_found_rows b.bandid, b.name, b.ename, b.intdate, b.comments, b.gname, b.gename
from bands b where b.status=0 order by b.dateadd desc limit 0, 30



C cортировкой по количеству:

select sql_calc_found_rows b.bandid, b.name, b.ename, b.intdate, b.comments, b.gname, b.gename
from bands b where b.bandstatus=0 order by b.comments desc limit 0, 30


C cортировкой по алфавиту:

select sql_calc_found_rows b.bandid, b.name, b.ename, b.intdate, b.comments, b.gname, b.gename
from bands b where b.bandstatus=0 order by find_in_set(b.firstchar, '9,8,7,6,5,4,3,2,1,0,z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,я,ю,э,ь,ы,ъ,щ,ш,ч,ц,х,ф,у,т,с,р,п,о,н,м,л,к,й,и,з,ж,ё,е,д,г,в,б,а') desc, b.firstchar limit 0, 30


Запросы выполняются примерно 900-1100 мс

В таблице около 100000 записей.

Кроме выбираемых в таблице еще довольно много текстовых полей.
Индекс на bandstatus создан составные ключи на status и поля по которым сортировка не использовались.

Планы запросы для выборок с разными сортировками одинаков:

План запроса:
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    b    ref    status    status    1    const    52723    Using where; Using filesort

Более подробно раскрыть структуры таблицы не могу. Хотелось бы получить хотя бы общий совет:
1) Можно ли как то заставить сортироватся по составным индексам
2) Имеет ли смысл нормализация и вынесении в отдельную таблицу текстовых полей, которые тут не используются

Неактивен

 

#2 30.12.2009 17:15:40

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

Re: Медленный запрос к одной таблице.

Сортировка по алфавиту отвратительная, сортируйте просто по firstchar.
Список индексов таки покажите smile

Скорее всего, индекса по (status, dateadd) хватит.

Неактивен

 

#3 30.12.2009 18:53:54

pt81
Участник
Зарегистрирован: 21.12.2009
Сообщений: 5

Re: Медленный запрос к одной таблице.

Добавил ключ на bandstatus и dateadd
Теперь запрос с сортировкой по dateadd идет меньше 100 мс что нормально.
Запрос с сортировкой по comments идет 500 мс
И с сортировкой по алфавиту более 1000 мс

Сортировка по алфавиту с использованием find_in_set обязательна по условию задачи.
План для сортировки по алфавиту:
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    b    ref    status,status_dateadd    status_dateadd    1    const    48483    Using where; Using filesort

Результат show keys:

Table    Non_unique    Key_name    Seq_in_index    Column_name    Collation    Cardinality    Sub_part    Packed    Null    Index_type    Comment
bands    0    PRIMARY    1    bandid    A    78255            (null)    BTREE    (null)
bands    1    status    1    bandstatus    A    1            (null)    BTREE    (null)
bands    1    dateadd    1    dateadd    A    78255            (null)    BTREE    (null)
bands    1    firstchar    1    firstchar    A    96            (null)    BTREE    (null)
bands    1    comments    1    comments    A    1            (null)    BTREE    (null)
bands    1    status_dateadd    1    bandstatus    A    1            (null)    BTREE    (null)
bands    1    status_dateadd    2    dateadd    A    78255            (null)    BTREE    (null)

Также показывают типы данных:

Field    Type    Null    Key    Default    Extra
comments    int(11)    NO    MUL    0    (null)
dateadd    int(11)    NO    MUL    0    (null)
bandstatus    tinyint(4)    NO    MUL    2    (null)
firstchar    char(1)    NO    MUL    (null)    (null)

Отредактированно pt81 (30.12.2009 18:56:37)

Неактивен

 

#4 30.12.2009 19:35:44

pt81
Участник
Зарегистрирован: 21.12.2009
Сообщений: 5

Re: Медленный запрос к одной таблице.

Я вижу что у ключа banstatus cardinality 1 в тоже время при использовании составного ключа status_dateadd используется только один символ из него.
Может ли ключ по статусу быть бесполезным.

upd: Нет убирать индекс с status не удастся все вообще тормозит и идет выборка - "ALL"

Распределение значений в столбце bandstatus:

bandstatus    сnt
0    52948
1    17177
2    5824
3    51

Отредактированно pt81 (30.12.2009 19:46:54)

Неактивен

 

#5 30.12.2009 20:26:50

pt81
Участник
Зарегистрирован: 21.12.2009
Сообщений: 5

Re: Медленный запрос к одной таблице.

Добавил индексы по status_comments и status_firstchar

теперь план запроса с сортировкой по алфавиту такой:

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    b    ref    status,status_dateadd,status_comments,status_firstchar    status    1    const    55287    Using where; Using filesort

C cортировкой по comments:

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    b    ref    status,status_dateadd,status_comments,status_firstchar    status_comments    1    const    55287    Using where

C cортировкой по dateadd

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    b    ref    status,status_dateadd,status_comments,status_firstchar    status_dateadd    1    const    55287    Using where

Для сортировки по comments и  dateadd составной ключ видит а для сортировки по алфавиту нет.

Изменять порядок столбцов в индекс пробывал, что то вроде dateadd_status работает еще хуже.
Остаются ли какие то выходы, кроме того как облегчит все это дела, вынесением текстовый столбцов из этой таблицы?

Отредактированно pt81 (30.12.2009 20:28:12)

Неактивен

 

#6 31.12.2009 10:41:20

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Медленный запрос к одной таблице.

pt81 написал:

Изменять порядок столбцов в индекс пробывал, что то вроде dateadd_status работает еще хуже.

Как использовать составные ключи, в каких случаях они работают?
См. http://sqlinfo.ru/forum/viewtopic.php?id=151


pt81 написал:

Для сортировки по comments и  dateadd составной ключ видит а для сортировки по алфавиту нет.

И не будет, так как вы используете find_in_set.
Если над индексируемым полем проводится какая-нибудь операция, то индекс не используется. Напрример:
SELECT .... WHERE 2*field=val; -- индекс по полю field использован не будет
SELECT .... WHERE field=val/2; -- индекс по полю field будет работать.

Вы можете создать дополнительное поле, в котором хранить результат вашего find_in_set и уже по нему делать составной индекс.

Неактивен

 

#7 31.12.2009 18:31:19

pt81
Участник
Зарегистрирован: 21.12.2009
Сообщений: 5

Re: Медленный запрос к одной таблице.

Варианты с отдельным полем и другими попытками избавитcя от find in set в order by я пробывал и они мне по тем или иным причинам не подошли.
Кроме того и сортивка с индексом status_dateadd по дате например, все равно использует только часть индекса - Extra
status_dateadd и работают ~300-500 мс что не мало. Думаю надо выносить в отдельную таблицу текстовые поля которые чаще всего не нужны в выборке их около 10-ти типа TEXT и VARCHAR(200) скорее всего из-за них и тормозит на 100000 записей..

Отредактированно pt81 (31.12.2009 18:33:27)

Неактивен

 

Board footer

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