Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> оптимальный индекс 
:(
    Опции темы
setnull
Дата 7.5.2013, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: нет
Всего: 1



Все здравствуйте!

объем 10-100 k записей
есть два естественных поля, являющиеся ключевыми при идентификации/сравнении записей и доступе к ним

Код

a int(11)
b int(11)


предусматривается интенсивное линейное сравнение записей по логике

Код

# условие 1
`t1`.`a` > `t2`.`a` || (`t1`.`a` = `t2`.`a` && `t1`.`b` > `t2`.`b`)


а также непосредственная сортировка
Код

order by 
`t`.`a`,
`t`.`b`


интересует, как данный доступ к записям организовать максимально эффективным с точки зрения производительности.

1. достаточно ли создать  составной индекс key(`a`, `b`)
1.1 правда ли, что в этом случае запрос с "условием 1" эффективней разбить на объединение (union) двух отдельных запросов с отдельными условиями , соединенными в "условии 1" через ||. Или MqSql сам эффективно и адекватно воспользуется индексом?
2. Или будет гораздо производительней создать дополнительно поле-нидекс 

Код

`ab` bigint = (`a` << 32)+`b`


с простыми дальнейшими сортировками и сравнениями 
Код

`t1`.`ab`> `t2`.`ab`

order by `t`.`ab`


С точки зрения сортировки, конечно, думаю разницы особой нет.
Больше интересует ситуация с || - условием. Корректно ли MySql воспользуется составным индексом в данном случае, т.к. вроде?

explain показывает, что в данном случае пользуется только индексом по полю `a`
Стоить заметить, что в данных одному значение`a` практически уникально, но возможны !редкие коллизии с небольшими вариациями по `b` в количествах думаю максимум 2-5 (самый потолок порядка 10) значений.


Т.е. в этом случае действительно оправдано игнорирование сервером второго индекса или все же 
 использовать union или сделать индекс по 'склеенному'  bigint'у будет эффективнее?

Спасибо!!!


PM MAIL   Вверх
Akina
Дата 7.5.2013, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



1. Да (впрочем, в зависимости от полной структуры и точного текста запроса возможны варианты)
1.1. Да, если использовать union all, иначе нет
2. Да (впрочем, есть ли тогда смысл раздельного хранения?) 


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
setnull
Дата 7.5.2013, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: нет
Всего: 1



Цитата(Akina @ 7.5.2013,  20:54)
1.1. Да, если использовать union all, иначе нет

имеется ввиду не union distinct?
я же так понимаю, условия `t1`.`a` > `t2`.`a` и `t1`.`a` = `t2`.`a` и так  абсолютно поделят множество... 
и в distinct и нет необходимости? 
или поправка именно в разрезе эффективности?

и еще уточню на всякий случай, хоть изначально предполагал для себя ответ) 
вопрос 1.1 звучал: эффективней ли разбить ИЛИ mysql гений оптимизации?
смею предположить ДА - эффективней?


Если рассматривать задачу исходя только из описанных критериев, какой подход самый оптимальный?
даже если не брать во внимание непосредственно аспект накладности  при самой возне с union и сравнивать исключительно по производительности доступа к данным

можно сказать, что подходы указаны в порядке ее увеличения или эффект в итоге получается единый?

Спасибо!
PM MAIL   Вверх
Akina
Дата 8.5.2013, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(setnull @  7.5.2013,  22:39 Найти цитируемый пост)
имеется ввиду не union distinct?

Я не знаю, чтотакое  union distinct.



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Zloxa
Дата 13.5.2013, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 33
Всего: 161



Цитата(Akina @  8.5.2013,  21:20 Найти цитируемый пост)
Я не знаю, чтотакое  union distinct.

Имеется в виду определенное стандартом как не обязательное для упоминания, но действующее по умолчанию ключевое слово http://dev.mysql.com/doc/refman/5.0/en/union.html


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Akina
Дата 13.5.2013, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Zloxa, ааа... а я пытался найти какой-то сакральный смысл... а то, что поведение по умолчанию ещё допускает и соотв. модификатор - ясен пень давно вылетело из головы.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Zloxa
Дата 13.5.2013, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 33
Всего: 161



Цитата(setnull @  7.5.2013,  22:39 Найти цитируемый пост)
и в distinct и нет необходимости? 

Для удовлетворения distinct требуетя дополнительная сортировка, в которой, в данном случае, нет необходимости в виду того, что критерии отбора не допускают дублирования записей в результирующем наборе.

Цитата(setnull @  7.5.2013,  21:05 Найти цитируемый пост)
1. достаточно ли создать  составной индекс key(`a`, `b`)

В частном случае, похоже что - да.
Условие "> `t2`.`a`" требует обособленного индекса по `a` или же составного, где `a` был бы упомянут первым
Условие "`= `t2`.`a` && > `t2`.`b`" требует составного индекса по `a` и `b` и, при том, что по `a` требуется прямой доступ, а по `b` требуется поиск по диапазону, `b` в составном индексе должен быть упомянут последним, `a` первым.

Оба критерия дополняют друг друга, для удовлетворения обоих критериев достаточно индекса по паре `a`,`b`

Цитата(setnull @  7.5.2013,  21:05 Найти цитируемый пост)
1.1 правда ли, что в этом случае запрос с "условием 1" эффективней разбить на объединение (union) двух отдельных запросов с отдельными условиями , соединенными в "условии 1" через ||. Или MqSql сам эффективно и адекватно воспользуется индексом?

Здесь надо смотреть на план в части критерия доступа, но, думаю что мася врядли cумеет объеденить результат двух разных предикатов доступа к одному индексу и запрос через union all выглядит как более надежный способ не сбить масю с понтолыку.

Однако есть один ньюанс - сортировка.
Требование сортировки заставляет оформлять запрос с union all в подзапрос и применять к результату сортировку. И тогда индекс для сортировки не сможет быть использован.

В принципе, думаю, не зазорно будет будет указать order by в каждом из подзапросов union all и надеяться на то, что объеденяться будут уже отсортированные множества. При этом, скорее всего, индекс сможет быть использован для сортировки. Думаю надежды оправдаются, но чтобы вместо надежд была уверенность, лучше бы ознакомиться с документацией по этому вопросу, гарантируется ли такое поведение. А тут я думаю, что врядли, ибо фиксация такого поведения в документации - это гвоздь в крышку гроба движка ибо для поддержки обратной совместимости придется отказаться от идеи параллелить выполнения объединяемых подзапросов в будущем.

Цена вопроса.
Мне кажется что игра не стоит свеч, и, в общем случае, усложнив запрос мы врядли выиграем достаточно спичек. Если для каждого значения `a` приблизительно одинаковое количество `b`, по критерию  && > `t2`.`b` будет отфильтрован из результата сравнительно не большой процент данных, и, я думаю, что такая оптимизация не даст сколь нибудь существенного профита против индексного доступа по предикату ">= `a`" и фильтарции по критерию "= `a` and > `b`". А для такого плана индекса по `а` - достаточно. `b` в хвост индекса можно добавить лишь для оптимизации сортировки. smile

Добавлено @ 11:24
Цитата(Zloxa @  13.5.2013,  12:11 Найти цитируемый пост)
Однако есть один ньюанс

Есть же еще один, самый главный ньюанс....

Судя по тому, как вы записываете критерии отбора, у вас производится селфджойн этой таблицы. Для лидирущей таблицы производится фуллскан, для выполнения объединения используется индекс. В этом случае, переписав запрос на union all вы, наверняка, получите два фуллскана вместо одного, что, скорее всего, более чем полностью нивелирует полученный вами профит от более точного отбора по индексу при объединении. Более того, при объединени больших наборов данных, вполне может оказаться более эффективным hash join(не знаю умеет ли его мася), который, в отличии от nested loop, не сможет использовать индекс.

Это сообщение отредактировал(а) Zloxa - 13.5.2013, 11:29


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
setnull
Дата 17.5.2013, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: нет
Всего: 1



Цитата(Zloxa @ 13.5.2013,  11:11)
Для удовлетворения distinct требуетя дополнительная сортировка, в которой, в данном случае, нет необходимости в виду того, что критерии отбора не допускают дублирования записей в результирующем наборе.

именно о чем я и говорил

Добавлено через 7 минут и 49 секунд
Цитата(Zloxa @ 13.5.2013,  11:11)
И тогда индекс для сортировки не сможет быть использован.

В принципе, думаю, не зазорно будет будет указать order by в каждом из подзапросов union all и надеяться на то, что объеденяться будут уже отсортированные множества.

да с этим и столкнулся...
к этому же и пришел..
сортирую внутри объединяемых подзапросов.
на данный момент отрабатывает - поднимать документацию и требовать клятвы на крови от разработчиков в оправданности подхода в дальнейшем особо нет времени )
в самом крайнем случае, думаю, можно будет прибегнуть к двум отдельным запросам с последующим собственноручным объединением их результатов.
PM MAIL   Вверх
setnull
Дата 17.5.2013, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: нет
Всего: 1



Цитата(Zloxa @ 13.5.2013,  11:11)
Судя по тому, как вы записываете критерии отбора, у вас производится селфджойн этой таблицы.

если Вы касательно
Код

# условие 1
`t1`.`a` > `t2`.`a` || (`t1`.`a` = `t2`.`a` && `t1`.`b` > `t2`.`b`)


t2 представлена единственной записью, являющейся опорной точкой, от которой происходит последующий отчет. Запись идентифицируется по строгому соответствию первичного ключа.
если с этим будут трудности t2 можно просто свести к литералам.


Всем спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0589 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.