SQL-запрос медленный? Должно ли это быть? - PullRequest
2 голосов
/ 12 сентября 2010

Используя SQLite, получили таблицу с ~ 10 столбцами. Theres ~ 25 миллионов строк.

Эта таблица имеет ИНДЕКС для 'sid, uid, area, type'.

Я запускаю выборку так:

SELECT sid from actions where uid=1234 and area=1 and type=2

Это возвращает мне 1571 результат и займет 4 минуты .

Это нормально?

Я далеко не эксперт по SQL, так что, надеюсь, кто-нибудь может рассказать мне о том, что мне не хватает. Почему это может занять 4+ минуты, когда все проиндексировано?

Какие-нибудь рекомендуемые ресурсы, чтобы узнать о достижении высокой производительности SQL? Я чувствую, что многие результаты Google просто дают мне мнения или анекдоты, я бы не отказался от твердой книги.

Ответы [ 4 ]

5 голосов
/ 12 сентября 2010

Создайте uid+area+type индекс вместо или uid+area+type+sid

2 голосов
/ 12 сентября 2010

Поскольку индекс начинается со столбца sid, он должен выполнить сканирование (начало в начале, чтение до конца) либо индекса, либо таблицы, чтобы найти ваши данные, соответствующие другим 3 столбцам. Это означает, что он должен прочитать все 25 миллионов строк, чтобы найти ответ. Даже если он читает только строки индекса, а не таблицы, это большая работа.

Представьте себе телефонную книгу большого города Нью-Йорка, организованную (с «индексом») Фамилия, Имя.

Вы отправляете SELECT [Last Name] FROM NewYorkPhoneBook WHERE [First Name] = 'Thelma'

Он должен прочитать все 25 миллионов записей, чтобы найти всех этих Тельм. Если вы не укажете фамилию, а затем сможете перейти непосредственно на страницу, где эта фамилия применяется впервые (поиск), или иметь индекс, организованный по имени (поиск по индексу с последующим поиском по таблице, иначе "поиск закладок"), нет никакого способа обойти это.

Индекс, который вы создадите для ускорения запроса, находится на uid, area, type. Вы можете включить sid, но не указывать его, если sid является частью первичного ключа.

Примечание. Таблицы часто имеют несколько индексов. Просто отметьте, что чем больше индексов, тем ниже скорость записи. Ненужные индексы могут снизить общую производительность, иногда радикально. Тестирование и в конечном итоге опыт помогут вам в этом. Кроме того, рассуждение об этом как о реальной проблеме (как примеры моей телефонной книги) может действительно помочь. Если это не имеет смысла для телефонных книг (и отдельных индексов телефонных книг), то, вероятно, не будет иметь смысла в базе данных.

Еще одна вещь: даже если вы поместите индекс в эти столбцы, если ваш запрос в конечном итоге будет тянуть большой процент строк в основной таблице, будет все равно дешевле сканировать таблицу, чем выполнять поиск по закладкам (ищите индекс, затем ищите таблицу для каждой найденной строки). Точный «переломный момент» в том, делать поиск закладок с поиском или сканировать таблицу, - это не то, что я могу сказать вам на макушке, но это основано на твердой математике.

2 голосов
/ 12 сентября 2010
  • Индекс не очень полезен, так как он начинается с неправильного поля ... что означает сканирование таблицы.

  • Похоже, у вас есть нормальныйКомпьютер там, а не то, что сделано для баз данных.Я запускаю табличное сканирование более чем 650 миллионов строк примерно за минуту на моем нижнем сервере базы данных, но это означает чтение примерно гигабайта в секунду с дисков, которые являются RAID-дисками с 10k RM - RAID 10. Просто скажу это в основном.... что базы данных любят IO, и это в той степени, которую вы никогда не видели раньше.В основном на больших серверах БД имеется много дисков, удовлетворяющих требованиям IOPS (IO в секунду).Я видел сервер с 190 дисками.

Итак, у вас есть два варианта: увеличить свои возможности IOPS (означает тратить деньги) или настроить индексы, которые используются, потому что они «правильные».

Правильное значение: индекс полезен только в том случае, если содержащиеся в нем поля используются слева направо.Не обязательно в том же порядке ... но если поле пропущено, существует вероятность того, что система SQL решит, что индекс не имеет смысла, и вместо этого выполнит сканирование таблицы (как в вашем случае).

0 голосов
/ 12 сентября 2010

Когда вы создаете свой новый индекс для uid, area и type, вы должны также сделать выборку для каждого из них, чтобы определить, у кого наименьшее количество различных записей, а затем создать индекс так, чтобы чем меньше различий, тем раньше они появляютсяв определении индекса.

...