|
|
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
hi all DDL (на новой базе): две таблицы, по одному int-полю в каждой, плюс индексы по этому полю: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. Статистика по индексам: Код: sql 1. 2. 3. Код: plaintext 1. 2. 3. 4. * в таблице `tm` = 1 запись - это следует из скрипта, см. выше * в таблице `td` = 1260020*0.00390625 = 4922 записей Далее делаю: var. 1 . Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Сразу вопрос-0 : почему ведущей таблицей была взята 'TD' ? var-2. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. Теперь вопрос-1 . Что удерживало оптизизатор от применения HJ в первом случае, когда условие соединения было без "плюс-нулей" ? И еще. var-3 . Заставляем его в варианте с NL взять ведущей таблицу `tm`: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Как видим, время выполнения на треть лучше, чем с hash join. Однако, по числу фетчей они почти равны, отличие на 1%. Поэтому вопрос-2 . Что там в hash join'e "заклинило", почему он проигрывает ? Построение hash-таблицы - его как-то можно будет отразить в статистике (особливо в трейсе, конечно :)) ? PS. LI-T3.0.0.30792, PAGE_SIZE 4096 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 20:17:26 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
Для сравнения - варианты 1 и 3 из предыдущего поста на LI-V2.5.3.26728 DDL: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. var-1. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. var-3. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 20:30:57 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
ТаблоидСразу вопрос-0: почему ведущей таблицей была взята 'TD' ? потому что с учетом существующей статистики это должно быть дешевле. Откуда оптимизатору знать, что в TM две трети записей напрочь отсутствуют в TD (насколько я понял из скрипта)? ТаблоидТеперь вопрос-1. Что удерживало оптизизатор от применения HJ в первом случае, когда условие соединения было без "плюс-нулей" ?HJ/MJ используются только при отсутствии индексов для полей связи. Со времен 2.х тут ничего пока не менялось. ТаблоидПоэтому вопрос-2. Что там в hash join'e "заклинило", почему он проигрывает ? понятия не имею, тем более я уже говорил что до беты он остается неоптимизированным и предназначенным для ловли багов. Но вообще-то он и не обязан выигрывать у NL во всех случаях. ТаблоидПостроение hash-таблицы - его как-то можно будет отразить в статистике (особливо в трейсе, конечно :)) ? нет, тем более не оно тормозит ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 20:52:07 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrТаблоидСразу вопрос-0: почему ведущей таблицей была взята 'TD' ? потому что с учетом существующей статистики это должно быть дешевле. Откуда оптимизатору знать, что в TM две трети записей напрочь отсутствуют в TD (насколько я понял из скрипта)?я не могу понять, как эта дешевизна следует из статистики. Если в исходном скрипте заменить Код: plaintext Код: plaintext исправленный скрипт, полностью Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. Код: plaintext 1. 2. 3. 4. И это означает, что на 1 уник. значение ключа в таблице `t m ` будет 4.94 записи. И хотя это значение ХУЖЕ, чем в первом варианте (там на 1 ключ была 1 запись), ФБ теперь соединяет так, как и должен был - делает ведущей таблицу `t m `: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. Только HJ всё равно лучше и при этом раскладе данных: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. А это значит, что эвристику:dimitrHJ/MJ используются только при отсутствии индексов для полей связи. Со времен 2.х тут ничего пока не менялось. - хотелось бы видеть уже более изворотливой. Это реально сделать в альфе или лучше не мечтать ? dimitrдо беты он остается неоптимизированным и предназначенным для ловли багов. Но вообще-то он и не обязан выигрывать у NL во всех случаях. <. . .> нет, тем более не оно тормозитВроде бы HJ должен выигрывать при соединении источников с сильно различающейся кардинальностью - а тут как раз такой случай. И еще: ты говоришь, что "не оно тормозит" - а что тогда ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 21:16:42 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
Таблоидя не могу понять, как эта дешевизна следует из статистики учитывай оба потока. В первом приближении: cost(NL) = cardinality(A) + cardinality(A) * cardinality(B) * selectivity(I) . ТаблоидА это значит, что эвристику хотелось бы видеть уже более изворотливой. Это реально сделать в альфе или лучше не мечтать ? и не мечтай ТаблоидИ еще: ты говоришь, что "не оно тормозит" - а что тогда ? пробирование хеш-таблицы может обходиться дороже, чем ее построение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 21:24:51 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrВ первом приближении: cost(NL) = cardinality(A) + cardinality(A) * cardinality(B) * selectivity(I) .Вот я снова читаю Писание и вижу там: авторИспользуются следующие формулы для оценки стоимости определенного порядка соединения: Код: plaintext 1. И правильно ли я понимаю, что selectivity(link) - это на самом деле selectivity(соответствующего_индекса_в_inner) - ? dimitrТаблоидА это значит, что эвристику хотелось бы видеть уже более изворотливой. Это реально сделать в альфе или лучше не мечтать ? и не мечтай dimitrпробирование хеш-таблицы может обходиться дороже, чем ее построениекак увидеть затраты на это ? можно ли будет патчик какой-то поиметь (хотя бы в isql set stat on чтобы отражалось) - ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 21:32:58 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
ЗЫ. Да, и еще хочу уточнить. Вот это вот:dimitrВ текущих версиях сервера стоимость определяется количеством логических чтений (страничных фетчей, page fetches) , необходимых для возврата всех записей методом доступа.- оно и в ТРЁШКЕ тоже так ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 21:35:03 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
ТаблоидЧто здесь есть indexScanCost - ? а перевести не судьба? :-) Стоимость скана индекса = высота дерева + число листовых страниц для данной выборки. ТаблоидИ правильно ли я понимаю, что selectivity(link) - это на самом деле selectivity(соответствующего_индекса_в_inner) - ? разумеется Таблоидкак увидеть затраты на это ? можно ли будет патчик какой-то поиметь (хотя бы в isql set stat on чтобы отражалось) - ? никак, нельзя. Потом возможно в плане это будет выводиться. Таблоидоно и в ТРЁШКЕ тоже так ? принципы оптимизации не менялись ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 21:39:06 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
Так. Я тут подсчитал кое-чё. По раскладу данных первого поста, для селективности индексов: Код: plaintext 1. 2. 3. Насколько я смог врубиться, формулы для расчета стоимости при NL следующие. 1. Когда ведущая таблица = 'T D ': Код: plaintext 1. 2. 2. Когда ведущая таблица = 'T M ': Код: plaintext 1. По данным gstat -r: Код: plaintext 1. 2. 3. 4. 5. 6. 7. gstat -r: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. I. Если я не перепутал ` * ` в indexScanCost_t * _x, то подставляя числа, получаем: 1. Когда ведущая таблица = 'T D ': Код: plaintext 1. 2. Код: plaintext 1. 2. II. Если же я перепутал с ` * ` в indexScanCost_t * _x и формулы для расчета фетчей должны быть такими: 1_upd. Код: plaintext Код: plaintext - то получаем вот это: 1. Когда ведущая таблица = 'T D ': Код: plaintext 2. Когда ведущая таблица = 'T M ': Код: plaintext А теперь смотрим на результат, который был показан в isql: Fetches = 8'846'440 Не сходится. Ни с чем, вообще. 2 dimitr: если я перепутал в обоих случаях и формула для расчета стоимости совсем не такая, то как её правильно записать ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 22:50:15 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrСтоимость скана индекса = высота дерева + число листовых страниц для данной выборки.А кстати: как он может быстро оценить число листовых страниц ? Да еще если доп. условие какое-нибудь наверчено на индексное поле! Это же только примитивный случай сейчас рассмотрен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 22:52:12 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
1) cardinality меряется в записях, а не в страницах 2) оценка никогда не будет равна реальному числу фетчей, ибо не учитываются фетчи для pointer pages ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 22:55:55 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
И таки снова цитата из Писания: dimitrГлавные критерии выбора: кардинальности обоих потоков и селективность условия связи. Используется следующие формул ы для оценки стоимости определенного порядка соединения: Код: plaintext 1. Последняя часть формулы определяет стоимость выборки из внутреннего потока на каждой итерации. Умножив ее на количество итераций, получаем общую стоимость выборки из внутреннего потока. Общая стоимость получается путем добавления стоимости выборки из внешнего потока. Из всех возможных перестановок выбирается вариант с наименьшей стоимостью. В процессе перебора вариантов отбрасываются заведомо худшие (на основании уже имеющейся стоимостной информации).Не понимаю фразу "Последняя часть формулы" - это ЧТО ИМЕННО, выдели цветом, плз! И еще. Вторая формула (в которой в левой части cardinality = ...) - она дальше как влияет на выбор ? Вот получили мы cost, затем получили эту самую 'cardinality' - и что, в куда её ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 22:59:51 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
Таблоидкак он может быстро оценить число листовых страниц ? Да еще если доп. условие какое-нибудь наверчено на индексное поле! все условия на индексное поле дают итоговую (умноженную) селективность. Общий размер индекса оценивается исходя из числа записей, длины индексного ключа и средней компрессии. Из этих двух цифр получается число листовых страниц нашего скана. Прикидка нифига не точная, но она влияет на итоговую оценку лишь во втором порядке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 22:59:58 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrcardinality меряется в записях, а не в страницахТогда и про число записей вопрос - такой же, как про число листовых страниц в индексе: 1) как он может так быстро определить их ? gstat -r трудится ведь минутами над этим вопросом... 2) учитывает ли он при этом версии записей (ведь их дохрена может случиться!) ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:01:43 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
ТаблоидНе понимаю фразу "Последняя часть формулы" - это ЧТО ИМЕННО, выдели цветом, плз! (indexScanCost + cardinality(inner) * selectivity(link)) ТаблоидИ еще. Вторая формула (в которой в левой части cardinality = ...) - она дальше как влияет на выбор ? Вот получили мы cost, затем получили эту самую 'cardinality' - и что, в куда её ? для джойна двух потоков - в никуда, для большего числа - вместо кардинальности внутреннего потока на предыдущем уровне рекурсии ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:03:59 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
Таблоид1) как он может так быстро определить их ? gstat -r трудится ведь минутами над этим вопросом... 2) учитывает ли он при этом версии записей (ведь их дохрена может случиться!) ? 1) ты понимаешь разницу между посчитать и прикинуть? Есть число страниц данных таблицы, есть длина распакованной записи, есть средняя степень сжатия. 2) нет конечно же, ибо не знает о них ты тут какой-то детский сад развел, ей-богу... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:06:17 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrОбщий размер индекса оценивается исходя из числа записей, длины индексного ключа и средней компрессии. Из этих двух цифр получается число листовых страниц нашего скана.Хорошо, вот фрагмент из gstat -r для индекса TD_X: Таблоид Код: plaintext 1. 2. У мну длина ключа = 4 байта. Число записей в таблице = 1'260'020, компрессия = 1.34 (ЕМНИП, это значит, что ключ жмётся в среднем до 4/1.34 "байта" - так ?). Получаем (4 / 1.34) * 1260020 / page_size = (4 / 1.34) * 1260020 / 4096 = ~ 918 - это и есть число листовых страниц при сканировании индекса TD_X ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:09:51 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrты тут какой-то детский сад развел, ей-богу...не, погодь!.. я в статью твою, как оказалось, не въехал. dimitrпонимаешь разницу между посчитать и прикинуть? Есть число страниц данных таблицы, есть длина распакованной записи, есть средняя степень сжатия.да, понимаю я эту разницу. Просто хочу теперь пройти тем же путём, что оптимизатор. Откудова он так быстро берёт вот эти сведения: 1) для таблиц: Код: plaintext 1. Код: plaintext 1. 2. Он вообще на ЭТО опирается в своём расчете или нет ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:17:42 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
ТаблоидУ мну длина ключа = 4 байта это ты фантазируешь ТаблоидПросто хочу теперь пройти тем же путём, что оптимизатор тогда читай код, я не буду здесь все до байта разжевывать ТаблоидОткудова он так быстро берёт вот эти сведения часть из них прикидывает, часть считает предопределенными (константы в коде) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:26:23 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
известно изначально: длина несжатой записи, длина несжатого ключа индекса определяется в рантайме: размер таблицы в страницах (для мелких таблиц - сразу в записях), средняя степень сжатия записей берется из статистики: селективность индекса берется из констант: глубина индекса, степень сжатия ключей индекса все остальное вычисляется ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:31:14 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrтогда читай код, я не буду здесь все до байта разжевыватья пока не готов к нанесению себе тяжелейшей мозговой травмы... ты лучше скажи прямо, по-пролетарски, как ПРАВИЛЬНО: так: Код: plaintext или вот так: Код: plaintext Мне надоело башку ломать, просто втупую подставлять буду, да и всё. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:38:21 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
Таблоид, бесполезно, утром прочитаешь и сам поймешь ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:43:08 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrопределяется в рантайме: размер таблицы в страницах (для мелких таблиц - сразу в записях), средняя степень сжатия записейэмпирически было установлено, что для здоровенных таблиц, типа широко известной в узких кругах "миллиардерши", ФБ достаточно долго делает первую вычитку. Но при втором и последующем обращениях к ней он строит план мгновенно. Если он запоминает "где-то в памяти" это число страниц, то как часто он обновляет эти сведения ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:43:45 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
dimitrбесполезно, утром прочитаешь и сам поймешьвряд ли... ладно - нет, значит нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:44:20 |
|
||
|
FB-3 hash join: какая эвристика заставляет его (не) применять при соединении таблиц ?
|
|||
|---|---|---|---|
|
#18+
Таблоидэмпирически было установлено, что для здоровенных таблиц, типа широко известной в узких кругах "миллиардерши", ФБ достаточно долго делает первую вычитку. Но при втором и последующем обращениях к ней он строит план мгновенно. Если он запоминает "где-то в памяти" это число страниц, то как часто он обновляет эти сведения ? ничего не запоминается и не обновляется, первая вычитка тормозит из-за дискового I/O, а потом помогает кеш ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2013, 23:47:18 |
|
||
|
|

start [/forum/topic.php?fid=40&fpage=106&tid=1564028]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
276ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
| others: | 233ms |
| total: | 608ms |

| 0 / 0 |
