Задавайте вопросы, мы ответим
Вы не зашли.
Добрый день
- есть 2 таблицы: А и B, процентов на 95% идентичные по используемым
полям. Основная разница между ними - по содержимому полей ID, которое
имеет вид: `ID` int(11) NOT NULL auto_increment,
(Во вложении - структура Таблиц в виде картинок)
В таблице А записи имеют поле ID со последовательными значениями, к
примеру: 1216,1217,1218.... и таких записей ~8.000
В таблице B записи имеют поле ID со непоследовательными значениями, к
примеру: 3852,3944,4052.... и таких записей ~5.000
Скорость выполнения команды (в порядке их выполнения):
select * from data_after order by BCCH limit 1000 - 1000 rows in set (2.25 sec)
select * from data_before order by BCCH limit 1000 - 1000 rows in set (0.03 sec)
И еще раз:
select * from data_after order by BCCH limit 1000 - 1000 rows in set (2.06 sec)
select * from data_before order by BCCH limit 1000 - 1000 rows in set (0.20 sec)
Создание индекса сильно не облегчает ситуацию:
mysql > create index IDX_BCCH on data_after (BCCH);
Query OK, 4961 rows affected (6.86 sec)
Records: 4961 Duplicates: 0 Warnings: 0
select * from data_after order by BCCH limit 1000;
1000 rows in set (1.25 sec)
Вот, собственно, вопрос: почему так и как можно исправить ситуацию?
Всем спасибо
Неактивен
Ох уж эта секретность. Думаете, названия полей всё испортят? Вот понимание
мной и Вами ситуации точно испортят
Что такое BCCH? Почему Вы сортируете по нему? Почему Вы утверждаете, что
таблички одинаковые, если в новой табличке добавился целый blob?
Ну, собственно, вот поэтому. И исправить можно, если не использовать blob там,
где не нужно, использовать индексы там, где нужно, и никогда не делать SELECT *.
Неактивен
Добрый день
Спасибо за ответ.
Я думаю, что человек всегда думает, когда что-то делает. Другое дело - верно ли он думает
Поле `BCCH` smallint(6) unsigned default NULL - 3-е в списке полей
Сортирую по нему только для примера: в итоговом варианте сортировка будет использоваться по многим полям, которые отображаются Пользователю в интерфейсе.
Таблицы не одинаковые и я это указал.
Другое дело, что у меня небыло понимания, что скорость выполнения запроса зависит не только от организации данных но и от размера самих данных (ну вот так...затмение, связанное с недостатком квалификации)
show table status показывает:
data_before:Data_length 11026432
data_after: Data_length 73973760
Разница в размерах - из-за содержания одного из blob-полей, которое есть в обеих таблицах, но содержимое-разное
Буду пробовать оптимизировать запрос SELECT...
Вопрос несколько другого характера (по OPTIMIZE TABLE):
- записи в таблицу data_before добавляются и удаляются по принципу FIFO
Удаление из таблицы data_before - это добавление записи в Таблицу data_after
- записи в таблице data_after удаляются в произвольном порядке
OPTIMIZE TABLE should be used if you have deleted a large part of a table or if you have made many changes...
Для таблицы из 2-х записей удаление одной - это уже large part of a table, но стоит ли для данного варианта делать оптимизацию?
Есть ли какие-то рекомендации, которые можно "привязать" к числовым данным: общее количество записей до удаления и сколько осталось, размер данных и т.д
Спасибо
Отредактированно flashSQL (04.03.2011 13:32:08)
Неактивен
Это написано, наверное, для табличек MyISAM, а Вы используете InnoDB?
Постарайтесь избавиться от BLOB — они никогда не кэшируются в памяти,
всегда идут на диск. OPTIMIZE не будет работать на InnoDB. Не используйте
SELECT *, выбирайте только нужные поля. Скорее всего, BLOB Вам не пона-
добятся.
Неактивен
Спасибо за помощь: select сделал по нужным полям-скорость стала правильной; от BLOB сразу отказаться не могу, но буду думать...
Неактивен
Вернулся снова с вопросом:
>> MySQL не может использовать индексы, чтобы выполнить ORDER BY когда cмешиваются ASC и DESC.
SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 ASC - не используются индексы.
А можно ли переписать вышеуказанное выражение так, чтобы индексы использовались?
Спасибо
Отредактированно flashSQL (24.03.2011 20:35:37)
Неактивен
Ну, например, если Вы будете хранить в key_part2 не само значение, а -значение,
то тогда сортировка будет в правильную сторону всегда
Но глобально, конечно, ответ — нет.
Неактивен
Спасибо за ответ.
Жаль, что чуда не случилось
Отредактированно flashSQL (25.03.2011 10:57:37)
Неактивен
Снова "неразрешимые" вопросы
Во вложении - протокол работы
Вопросы:
- почему для запроса select bcch from data_before order by ta; не используется индекс (в explain поле Extra=[])?
- как можно изменить запрос или структуру полей/индексов, чтобы запросы типа
select bcch, ta order by ta (bcch) asc(desc) (при условии, что есть индекс(s) по выбираемым полям или набору полей) выполнялись соизмеримо со временем запросов без ORDER?
PS: В моем случае, к минимум, нужно для столбцов не использовать Default значение = null, иначе запрос с DESC не будет использовать индекс.
Спасибо
Отредактированно flashSQL (27.03.2011 18:07:19)
Неактивен
Когда Вы выбираете все данные из таблицы, оказывается, что выбирать все
данные последовательно, а потом сортировать в памяти, быстрее, чем выби-
рать их по индексу. Это связано с тем, что перемещение головки диска для
выбора следующей записи по индексу больше, чем аналогичная сортировка
строки в памяти. Оптимизатор будет предпочитать индекс только в случае
выбора небольшого количества строк.
Неактивен
Не понял ответа, извините.
Ниже описаны два запроса, которые выбирают все записи, но разница в скорости выполнения - громадная
select bcch from data_before order by bcch; - 12538 rows in set (0.14 sec)
select bcch from data_before order by ta; - 12538 rows in set (11.58 sec)
Понятно, почему так: explain описывает [Using index] в первом случае и [] во втором.
Но почему оптимизатор не использует индексы во втором случае и как его заставить это сделать?
PS: Для понимания, моя задача:
- таблица имеет большое количество записей, стремящееся к огромному
- запрос select выполняется с фиксированным набором и порядком полей: select P1,P2,P3,...Pn from ...;
- используется LIMIT;
- нужно быстро (~0.x сек.) выводит информацию из таблицы с использованием OPRDER [DESC] по любому из полей P1,P2,P3,...Pn;
Отредактированно flashSQL (28.03.2011 12:41:20)
Неактивен
Хм. Представьте себе класс с учениками. Обычный класс. В одном случае
Вы просите назвать фамилии учеников (с сортировкой по фамилии). Для
этих целей можно взять журнал и прочитать их оттуда (using index). Во вто-
ром случае Вы просите назвать фамилии учеников, но с сортировкой по
цвету ботинок. В данном случае проще взять всех учеников, рассортиро-
вать по цвету ботинок в коридоре, выставив в линеечку, а потом попросить
каждого назвать свою фамилию.
Так понятнее?
А ответ на вопрос «почему нельзя сделать журнал соответствий цвета тапок
с фамилией» я дал в предыдущем сообщении: заставить учеников посорти-
роваться в коридоре быстрее, чем проверить по этому журналу, в тех ли
тапках каждый сегодня пришел.
Неактивен
Извините, все равно - нет (краснею)
Если отталкиваться от этого, что
paulus написал:
ответ на вопрос «почему нельзя сделать журнал соответствий цвета тапок с фамилией» .... в тех ли тапках каждый сегодня пришел.
то почему это не распространяется на журнал с фамилиями - ведь в классе сегодня может появиться новый ученик с новой фамилией?
Как я вижу эту ситуацию с фамилиями и цветом ботинок:
Есть Класс, где есть ученики - это таблица.
Есть журнал1, где ученики отсортированы по фамилиям - это индекс по Фамилии на Класс;
Есть журнал2, где ученики отсортировны по цвету ботинок - это индекс по Цвету ботинок на Класс;
Прошу назвать Фамилии учеников (с сортировкой по Фамилии) - обращаемся к Классу через журнал1
Прошу назвать Фамилии учеников (с сортировкой по Цвету ботинок) - обращаемся к Классу через журнал2
Где я ошибаюсь в свои рассуждениях?
Видимо, дело в том, что я неправильно понимаю саму суть Индекса как сущности?
Отредактированно flashSQL (28.03.2011 20:09:53)
Неактивен
Ммм... тогда попробую другой пример. Строки — это коробки. Коробки выглядят
все одинаково, но у них есть содержимое. В качестве содержимого выберем, напри-
мер, какие-нибудь цветные объекты. Индекс — это бумажка, на которой в сорти-
рованном виде написано о том, что находится в коробках.
Индекс по форме: бумажка, на которой написано «шар находится в в седьмой слева
коробке, в 154й и в 23й; в девятнадцатой — геоид, эллипсоид — в первой и 37й, ...
в одиннадцатой — куб» (немного сложно сортировать, но идею Вы поняли).
Индекс по цвету: бумажка, на которой написано «красное лежит в пятой, шестой и
119й, оранжевое — в 74й, ... фиолетовое — в 59й».
Ваш вопрос — «назовите все фигуры, которые есть в коробках, с сортировкой по
фигуре». Очевидное решение — первый индекс. Второй вопрос — «назовите все
фигуры с сортировкой по цвету». Вы можете взять второй индекс и начать бегать
по нему — пойти к шестой коробке, посмотреть, что там, потом — к 119й, потом
вернуться к 74й и так далее. Это не очень эффективно. Куда проще идти слева
направо, заглядывая в каждую коробку и запоминая, что Вы там увидели (или
выписывая на листочке, если памяти не хватает).
Для сравнения — тот же второй вопрос, но когда Вам нужно обежать не всю табли-
цу, а, скажем, 10 ящиков (LIMIT 10) — Вам безусловно выгоднее побегать по второ-
му индексу и посмотреть, что лежит непосредственно в этих 10 ящиках.
P.S. А ученик с новой фамилией появиться может, и его добавляют в школах в конец
журнала только в первый месяц из-за несовершенства технологии, а потом его пере-
писывают по алфавиту так, как и положено. В индексе мы можем себе позволить
записать его сразу по алфавиту.
Неактивен
Спасибо за такое полное объяснение - теперь все понятно, почему-так.
Все же я не понимал сути Индекса...и заставлял Вас тратить свое время не меня (краснею)
Неактивен
Для пущего понимания природы Индекса рекомендую посмотреть здесь :
http://people.ksp.sk/~kuko/bak/index.html
Неактивен
Отличная демонстрация функционирования деревьев поиска !!!
PS: Я, в своих вопросах, так далеко не заходил-запутался в 3-х соснах
Неактивен
Написал запрос sakila@sqlinfo.ru о коммерческой помощи - хватит мучать себя и других
Пока жду ответа, еще вопрос: можно ли перестроить указанный запрос (во вложении), чтобы не использовался
Using filesort?
Всем спасибо
Неактивен
Сделать индекс на (`result_decip`,DT_START)
Неактивен
vasya написал:
Сделать индекс на (`result_decip`,DT_START)
Спасибо большое
Встречный вопрос: да, написано в документации, как MySQL оптимизирует...., но "уложить" все в стройную линию новичку (мне) все стороны хорошо не получается.
Посоветуйте, пожалуйста, ресурсы или статьи, где вопрос правильного пострения запросов, с точки зрения оптимизации, изложен более популярно, что ли...
Понятно, что истина скрывается вот в этой фразе из документации:
""Оптимизация - сложная задача, потому что она, в конечном счете, требует понимания системы в целом... "
PS: Никто не отклкнулся с sakila@sqlinfo.ru - пойду в народ
Нет, пойду позвоню, все таки.....
Отредактированно flashSQL (30.03.2011 12:12:43)
Неактивен
Безобразие, что не ответили Будем исправляться
Есть курс оптимизации, но на него, разумеется, нужно время.
Неактивен
paulus написал:
Безобразие, что не ответили Будем исправляться
На звонок - ответили, первоначально все согласовали, спасибо.
Неактивен