![]()  | 
		
Задавайте вопросы, мы ответим
Вы не зашли.
Нужно выбирать данные из некоторой таблицы с разными видами сортировок, привожу примеры запросов:
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) Имеет ли смысл нормализация и вынесении в отдельную таблицу текстовых полей, которые тут не используются
Неактивен

Сортировка по алфавиту отвратительная, сортируйте просто по firstchar.
Список индексов таки покажите ![]()
Скорее всего, индекса по (status, dateadd) хватит.
Неактивен
Добавил ключ на 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)
Неактивен
Я вижу что у ключа 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)
Неактивен
Добавил индексы по 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)
Неактивен

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 и уже по нему делать составной индекс.
Неактивен
Варианты с отдельным полем и другими попытками избавит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)
Неактивен