|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
Всем доброго дня, столкнулся с проблемой, есть простой запрос: Код: sql 1.
вот план PLAN (PUR NATURAL) почему не используется индекс FK_PROUSERROLES_PRO? Код: sql 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. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 11:31 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun, это был упрощённый пример, тут он тоже не используется: Код: sql 1.
PLAN SORT (JOIN (PRO NATURAL, PUR INDEX (FK_PROUSERROLES_PRO))) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 11:36 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
а если так то используется: Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 11:38 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotunпочему не используется индекс FK_PROUSERROLES_PRO? Здесь как минимум потому что индекс бесполезен) У вас поле "not null" и вы условие поставили is not null - зачем индекс?? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 11:43 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
a7exander, ок, not null опустим почему тут не используется? Код: sql 1.
Plan -------------------------------------------------------------------------------- PLAN SORT (JOIN (PRO NATURAL, PUR INDEX (FK_PROUSERROLES_PRO))) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 11:44 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun, сорри, просмотрел, там DISTINCT и на нём спотыкается а индекс используется ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 11:46 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun a7exander, ок, not null опустим почему тут не используется? Код: sql 1.
может кто то не умеет читать план? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 11:50 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun, блин, но почему тогда Код: sql 1.
не пользует primary key PLAN SORT ((PRO NATURAL)) Код: sql 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. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 11:50 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun, ну какой primary key? Вы же условие никакое не ставите! Поставьте хотя order. Может будет перебирать по primary key. Опять же - какой смысл? Что Вы хотите? В Вашем случае по натуралу самый быстрый поиск. ФБ рулит!!! Я бы возмутился в обратном случае - зачем дёргать индексы, если надо проверить тупо все записи? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 14:29 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun, какой смысл в distinct, если выбирается только PK ? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 14:33 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hvlad hlopotun, какой смысл в distinct, если выбирается только PK ? да, действительно. Извиняюсь. Неудачно обрезал пример, потерялся смысл, полный код выглядит так: Код: sql 1. 2. 3. 4. 5. 6. 7.
и проблема в этой части Код: sql 1.
Plan -------------------------------------------------------------------------------- PLAN SORT ((V TK_TECHORDERS INDEX (IDX_TK_TECHORDERS_UPDT))) PLAN (V TK_TECHOBJECTS INDEX (RDB$FOREIGN25)) PLAN (V TK_SITEINFOS INDEX (IDX_TK_SITEINFOS_TO)) PLAN (V TK_SITEINFOS INDEX (IDX_TK_SITEINFOS_TO)) PLAN SORT ((V TK_PURCHASEORDERS INDEX (IDX_TK_PURCHASEORDERS_UPDT))) PLAN MERGE (SORT (SORT (JOIN (JOIN (JOIN (ROLES U V_85_ZAVUSERROLES U INDEX (IDX_ZAVUSER_USERNAME), ROLES U V_85_ZAVUSERROLES RA INDEX (PKUSERROLES)), ROLES U V_85_ZAVUSERROLES RS INDEX (PKUSERROLES)), JOIN (ROLES PRO NATURAL, ROLES PUR INDEX (FK_PROUSERROLES_PRO))))), SORT (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (V A INDEX (RDB$PRIMARY4), V PRO INDEX (RDB$PRIMARY2)), V BL INDEX (RDB$PRIMARY17)), V BEARB INDEX (RDB$PRIMARY17)), V AUFMBEARB INDEX (RDB$PRIMARY17)), V TECHORD INDEX (RDB$PRIMARY22)), V TECHOBJ INDEX (RDB$PRIMARY24)), V SI_A INDEX (RDB$PRIMARY27)), V SI_B INDEX (RDB$PRIMARY27)), V POORD INDEX (RDB$PRIMARY30)), V B INDEX (RDB$PRIMARY4)), V SEN SE ORDER IDX_TK_SERVICEENTRIES_DTAG_ASC INDEX (IDX_TK_SERVICEENTRIES_DTAG_ASC)))) Adapted Plan -------------------------------------------------------------------------------- PLAN SORT ((V TK_TECHORDERS INDEX (IDX_TK_TECHORDERS_UPDT))) PLAN (V TK_TECHOBJECTS INDEX (INTEG_86)) PLAN (V TK_SITEINFOS INDEX (IDX_TK_SITEINFOS_TO)) PLAN (V TK_SITEINFOS INDEX (IDX_TK_SITEINFOS_TO)) PLAN SORT ((V TK_PURCHASEORDERS INDEX (IDX_TK_PURCHASEORDERS_UPDT))) PLAN MERGE (SORT (SORT (JOIN (JOIN (JOIN (ROLES U V_85_ZAVUSERROLES U INDEX (IDX_ZAVUSER_USERNAME), ROLES U V_85_ZAVUSERROLES RA INDEX (PKUSERROLES)), ROLES U V_85_ZAVUSERROLES RS INDEX (PKUSERROLES)), JOIN ( ROLES PRO NATURAL , ROLES PUR INDEX (FK_PROUSERROLES_PRO))))), SORT (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (JOIN (V A INDEX (INTEG_12), V PRO INDEX (INTEG_6)), V BL INDEX (INTEG_57)), V BEARB INDEX (INTEG_57)), V AUFMBEARB INDEX (INTEG_57)), V TECHORD INDEX (INTEG_62)), V TECHOBJ INDEX (INTEG_64)), V SI_A INDEX (INTEG_67)), V SI_B INDEX (INTEG_67)), V POORD INDEX (INTEG_100)), V B INDEX (INTEG_12)), V SEN SE ORDER IDX_TK_SERVICEENTRIES_DTAG_ASC INDEX (IDX_TK_SERVICEENTRIES_DTAG_ASC)))) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 15:38 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun и проблема в этой части Код: sql 1.
JOIN ( ROLES PRO NATURAL , ROLES PUR INDEX (FK_PROUSERROLES_PRO)) Если есть доп. условия, то могут быть использованы доп. индексы. Но здесь не этот случай. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 15:46 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun, если точнее вот вырезанный кусок: select distinct pro.proid as pid, u.id, u.username, u.isadmin from projekte pro LEFT JOIN prouserroles pur ON pur.proid=pro.proid RIGHT JOIN (select username, isadmin, id from v_85_zavuserroles where (username = 'SYSOP')) u ON u.ID = pur.userid or u.isadmin = 'T' Plan -------------------------------------------------------------------------------- PLAN SORT (JOIN (JOIN (JOIN (U V_85_ZAVUSERROLES U INDEX (IDX_ZAVUSER_USERNAME), U V_85_ZAVUSERROLES RA INDEX (PKUSERROLES)), U V_85_ZAVUSERROLES RS INDEX (PKUSERROLES)), JOIN (PRO NATURAL, PUR INDEX (FK_PROUSERROLES_PRO)))) и его Performance Analysis ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 15:52 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hvlad, ok, понятно. Спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
04.11.2021, 15:53 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
hlopotun JOIN (PRO NATURAL, PUR INDEX (FK_PROUSERROLES_PRO)))) в left/right join без дополнительных условий таблица со стороны left (или right) всегда читается натуралом. Как вы себе представляете альтернативу? На пальцах попробуйте придумать (я не шучу, перебрать соответствие всех пальцев одной руки и части пальцев на другой). ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2021, 22:22 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
kdv Как вы себе представляете альтернативу? Если соединяется по условию PK=FK, то по-идее merge join должен использовать индексы обеих таблиц для сортировки, а соединение получаться уже даром. Вопрос в том, почему Firebird не хочет использовать merge join в этом случае. Мне кажется, что join двух больших таблиц должен в этом случае работать значительно быстрее. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 13:06 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
ggreggoryЕсли соединяется по условию PK=FK, то по-идее merge join должен использовать индексы обеих таблиц для сортировки Еще раз: a left join b on a.id = b.id здесь из A выбираются ВСЕ записи, зачем в этом случае использовать индекс, merge join и прочие ужасы? Тут достаточно прохода по всем записям по A с индексным поиском в B. И план выглядит как PLAN (A NATURAL, B INDEX ...) не надо тут больше ничего придумывать, это максимально оптимально выполняется. Вот если есть доп. условие по A - да, будет индекс использоваться. Или если нет индекса по B, то тогда будет hash join (в ФБ 3). Вы лучше почитайте https://www.ibase.ru/dataaccesspaths ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 14:36 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
kdv не надо тут больше ничего придумывать, это максимально оптимально выполняется. Угу. Не только вы можете кидаться статейками, я тоже могу: автор ...соединение слиянием очень часто является лучшим выбором для соединения больших наборов данных.. Ведь элементарная логика. Если в таблице А 1000000 (миллион) записей, а таблице В миллион записей, то чтобы присоединить их по вашему алгоритму, надо считать миллион записей из первой таблицы и для каждой логарифм от миллиона записей второй таблицы, т.е. 30 миллионов. А алгоритм слияния считывает обе по индексу и в итоге считывается 2 миллиона записей, т.е. он будет в 15 раз быстрее работать. Грубая оценка, но всё же... ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 14:56 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
ggreggoryГрубая оценка, но всё же... Не только грубая, но и просто неверная. При "считывает обе по индексу" получается тот же самый логарифм, только с обеих сторон. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 15:09 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
ggreggoryНе только вы можете кидаться статейками, я тоже могу: я вам про Firebird, вы мне про MS SQL ggreggoryА алгоритм слияния считывает обе по индексу и в итоге считывается 2 миллиона записей, т.е. он будет в 15 раз быстрее работать. если вы про самое начало статьи, то там есть фраза: "Например, если мы имеем предикат соединения "T1.a = T2.b", таблица T1 должна быть отсортирована по T1.a, а таблица T2 должна быть сортирована по T2.b. Соединение слиянием одновременно считывает и сравнивает два отсортированных входных потока, по одной строке за шаг." в Firebird это называется SORT MERGE. В плане это MERGE (TABLE1 SORT, TABLE2 SORT). Причем, SORT это либо действительно сортировка (во временном файле), либо это проход в порядке индекса. Но в обоих случаях это однозначно ХУЖЕ чем PLAN (TABLE1 NATURAL, TABLE2 index ...). Кстати, вместо MERGE SORT в ФБ 3 уже есть HASH JOIN. В общем, кое-что, конечно, в упомянутой вами статье является общим для оптимизаторов, но детали могут отличаться, поэтому не стоит верить что вот если "этот метод доступа лучше другого в сервере А". В сервере Б это не обязательно будет так. (и примеры тому были на Хабре, когда там забубенная статья про использование индексов для where у PG, MS SQL и Oracle, а в ФБ не так и в половине случаев быстрее). ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 15:18 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
kdv я вам про Firebird, вы мне про MS SQL Это понятно, я ведь вначале написал "вопрос в том, почему Firebird не хочет". И да, я пробовал планы подсовывать - не кушает. ggreggoryлибо это проход в порядке индекса При соединении PK=FK всегда есть индексы ключей. Поэтому там никакой сортировки во временных файлах или памяти не нужно. Если 3-ий Firebird, SuperServer и кэш большой, то это совсем не затратно (о чём там Dimitry Sibiryakov ??? - непонятно). kdv В сервере Б это не обязательно будет так. В Firebird-е на чтение накладывает свой отпечаток наличие версий и необходимости считывать страницы данных. Но эта же проблема будет и при поиске по индексу. Так что вопрос остается открытым. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 17:41 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
ggreggory, продолжаем. ggreggory"надо считать миллион записей из первой таблицы и для каждой логарифм от миллиона записей второй таблицы, т.е. 30 миллионов. непонятно, откуда такая логика. При плане JOIN (A NATURAL, B INDEX (BYID))) механизм выборки данных такой: по мере прохода по всем записям A берем значение поля связи и ищем его в индексе BYID таблицы B. Полученные из индекса номера записей складываем в "битовую маску". Где тут логарифмы и 30 миллионов - вообще непонятно. ggreggory"вопрос в том, почему Firebird не хочет" потому что Firebird это не MS SQL. Он по другому делает много чего, в т.ч. и оптимизатор работает иначе. Вы еще к Ораклу претензию дайте, почему он не так как MS SQL оптимизирует. ggreggoryПри соединении PK=FK всегда есть индексы ключей. Поэтому там никакой сортировки во временных файлах или памяти не нужно Ну вот опять, еще раз - в плане выше как раз используется индекс по FK таблицы B. Вам не нравится, что не используется индекс по ПК таблицы А. Но нафиг он тут нужен, если из-за A LEFT JOIN B надо прочитать всю таблицу A? Чтение индекса таблицы A будет абсолютно лишним. ggreggoryВ Firebird-е на чтение накладывает свой отпечаток наличие версий и необходимости считывать страницы данных. А другие серверы волшебным образом читают не "страницами", а "записями", что-ли? Или я вас не понимаю. Ну версии, и что. Включите в MS SQL версионность, и там будет то же самое. А в Оракле версионность по умолчанию. И? ggreggoryИ да, я пробовал планы подсовывать - не кушает. как я понимаю, начитавшись статей по MS SQL вы хотите заставить Firebird, чтобы он работал так же. Ну, успехов... ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 18:07 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
ggreggoryЕсли 3-ий Firebird, SuperServer и кэш большой, то это совсем не затратно (о чём там Dimitry Sibiryakov ??? - непонятно). Чтобы было понятно, таки надо прочитать статью на которую дали ссылку. NATURAL это 2 фетча на запись. INDEX это (при глубине индекса 3) 5 фетчей на запись. Теперь считаем: Nested loop(NATURAL + INDEX) = 7 фетчей на запись. Merge (INDEX + INDEX) = 10 фетчей на запись. Итого для двух миллионных таблиц это 7 миллионов фетчей против 10. Натуралы выигрывают. Откуда MS SQL при том же раскладе умудряется делать 30 миллионов фетчей - его проблема. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 18:34 |
|
Почему FB 2.5.8 не использует FK индекс в запросе
|
|||
---|---|---|---|
#18+
Проиллюстрирую примером. Сделать в Firebird-е запрос с нужным планом не могу, но могу написать процедуры, эмулирующие эту ситуацию: Код: sql 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. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82.
у меня среднее время выполнения на FB3 Superserver с достаточным кэшем select count(*) from test_index = 26 секунд select count(*) from test_merge = 19 секунд В обоих случаях всё в памяти, Reads from disk to cache = 0. Т.е. получается, что вариант MERGE быстрее варианта INDEX на 7 секунд. Я понимаю, разница не большая, но там наибольшие потери в том, что это сделано в виде процедуры, а не обычного запроса. Среднее время выполнения select count(*) from (select tbl.text, join_tbl.text as join_text from tbl join join_tbl on tbl.id = join_tbl.id) у меня 10 секунд. Таким образом если бы этот запрос делался не по индексу, а объединением, т.е. быстрее на 7 секунд, то это уже было бы 10-7=3 секунды. Сравните - 3 секунды и 10 секунд. Это в три с лишним раза быстрее!!! ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2021, 20:57 |
|
|
start [/forum/topic.php?fid=40&fpage=3&tid=1559895]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
26ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
69ms |
get tp. blocked users: |
2ms |
others: | 269ms |
total: | 412ms |
0 / 0 |