• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Правильная расстановка индексов

  • Автор темы Black Rabbit
  • Дата начала
Статус
Закрыто для дальнейших ответов.
B

Black Rabbit

Привет всем
Есть таблица, описывающая свойства продукции. Структура такая:

`pid` - int(10) - айди продукта
`oid` - int(10) - айди свойства
`value` - text - значение этого свойства

По ней необходимо организовать поиск, параметры поиска поступают как набор пар oid - value. Надо найти айди продукции, удовлетворяющие этому условию
Пример запроса:
select* from options_filled where (oid='26' and value='0') or (oid='29' and value>='10') or (oid='33' and value='0') group by oid,pid

Число записей - 119,232
Когда делаю индекс по полям (oid, value) - выборка идет за 0,2 сек
Если ставлю индекс только на oid - то за 0,39 сек
Без индексов - 0,15 сек

Если верить документации, первый вариант правильный

Как следует расставить индексы, чтобы поиск шел максимально эффективно?
 
B

Barmutik

Индексы начинают давать выигрыш начиная с определённого объёма данных..

Вполне возможно что Вы его ещё не перешагнули.. надо посмотреть план выполнения запроса и тогда уже решать почему в варианте без индексов работает бычтрее...
 
E

European

Полностью согласен с Barmutik по поводу плана выполнения запроса... Я бы еще попробовал не объединять условия по OR, а выполнить каждый запрос отдельно, объединяя результат по UNION
 
A

Andromeda

1) Какие поля в таблице обеспечивают уникальность? То есть, есть ли ограничения типа UNIQUE хотя бы для одного поля?
Если таковые есть, то индекс для такого поля строится автоматически! Индексировать такие поля нельзя!

2) Как правильно замечено - надо смотреть план запроса, так как наличие индексов не гарантирует их использование оптимизатором. И наоборот, то что ты не создал индекс вовсе не означает, что его нет ;)

3) Есть зависимость от СУБД. В Firebird лучше создать два индекса, а в Oracle можно и один составной. Опять же, если индексы не созданы для обеспечения ограничений (constraints).
 
B

Black Rabbit

СУБД - MySQL 4.1.14
Никаких ограничений вроде UNIQUE нету
Изменила тип поля value, вместо text сделала его float, индексы оставила как было - на pid и составной на (oid,value)
Теперь все работает очень быстро даже на миллион записей
Всем спасибо за помощь
 
E

European

<!--QuoteBegin-Black Rabbit+11:12:2006, 12:44 -->
<span class="vbquote">(Black Rabbit @ 11:12:2006, 12:44 )</span><!--QuoteEBegin-->Изменила тип поля value, вместо text сделала его float
[snapback]50413" rel="nofollow" target="_blank[/snapback]​
[/quote]
А это вообще влиять на поиск никак не должно! Кстати, а где первичный ключ?
 
A

Andromeda

К своему стыду :((( не знаю особенности MySQL, но вот сейчас присмотрелся к первому посту и вижу вот что:
- поле oid целое, а value - текстовое;
- условие отбора в select к полям одинаково построено ->
select* from options_filled where (oid='26' and value='0') or (....
как к текстовым полям (значения в кавычках). Не значит ли это, что при выполнении запроса происходит еще и авто-преобразование типов?
 
B

Black Rabbit

Странно.... у меня влияет
Создаю копированием (индекс только на pid) 2 абсолютно идентичные таблицы, разница только в типе поля value.
Делаю запрос
select * from inf_test3 as opt
inner join inf_prod as pr on opt.pid=pr.id
where (opt.oid='1' and opt.value='1') or (opt.oid='2' and opt.value>='10') or
(opt.oid='6' and opt.value='0') or (opt.oid='24' and opt.value='0')
or (opt.oid='31' and opt.value='0') or (opt.oid='34' and opt.value='0')
or (opt.oid='35' and opt.value='14') or (opt.oid='37' and opt.value='2')

результаты - 12,4 сек там где тип текст
и 6,3 сек там где флоат
ставлю индекс - из обеих порядка 1сек :)

Кстати, протестировала тот запрос, все летает. Возможно вчера что-то с сервером было....
Извините за беспокойство
 
A

Andromeda

Ага, а еще вчера у тебя был GROUP BY... :)
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!