|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
Есть запрос из битрикса, который сильно тормозит. Исходный запрос. Выполняется 12.5 секунд, и фетч 0.125 Код: plsql 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.
План запроса, все по индексам { "query_block": { "select_id": 1, "filesort": { "temporary_table": { "function": "buffer", "table": { "table_name": "BE", "access_type": "index_merge", "possible_keys": [ "ix_iblock_element_1", "ix_iblock_element_4", "ix_iblock_element_3", "ix_iblock_element_code", "ix_iblock_element_openregion_3", "idx_b_iblock_element_ACTIVE", "idx_b_iblock_element_WF_STATUS_ID" ], "key_length": "3,4,5,5", "index_merge": { "intersect": { "range": { "key": "idx_b_iblock_element_ACTIVE", "used_key_parts": ["ACTIVE"] }, "range": { "key": "ix_iblock_element_openregion_3", "used_key_parts": ["IBLOCK_ID"] }, "range": { "key": "ix_iblock_element_3", "used_key_parts": ["WF_PARENT_ELEMENT_ID"] }, "range": { "key": "idx_b_iblock_element_WF_STATUS_ID", "used_key_parts": ["WF_STATUS_ID"] } } }, "rows": 23529, "filtered": 75.001, "attached_condition": "((BE.WF_STATUS_ID = 1) and (BE.IBLOCK_ID = '2') and (BE.ACTIVE = 'Y') and isnull(BE.WF_PARENT_ELEMENT_ID))" }, "table": { "table_name": "B", "access_type": "eq_ref", "possible_keys": ["PRIMARY", "b_iblock_LID_IDX_openregion"], "key": "PRIMARY", "key_length": "4", "used_key_parts": ["ID"], "ref": ["letters.BE.IBLOCK_ID"], "rows": 1, "filtered": 100 }, "table": { "table_name": "b_iblock_site", "access_type": "eq_ref", "possible_keys": ["PRIMARY", "idx_b_iblock_site_SITE_ID"], "key": "PRIMARY", "key_length": "10", "used_key_parts": ["IBLOCK_ID", "SITE_ID"], "ref": ["letters.BE.IBLOCK_ID", "const"], "rows": 1, "filtered": 100, "attached_condition": "(b_iblock_site.SITE_ID = 's2')", "using_index": true }, "table": { "table_name": "L", "access_type": "ALL", "possible_keys": ["PRIMARY"], "rows": 1, "filtered": 100, "attached_condition": "(L.LID = B.LID)" } } } } } А теперь просто уменьшим количество возвращаемых полей, не меняя выборку... запрос выполняется 2 секунды... Запрос Код: plsql 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.
План запроса не изменился { "query_block": { "select_id": 1, "filesort": { "temporary_table": { "function": "buffer", "table": { "table_name": "BE", "access_type": "index_merge", "possible_keys": [ "ix_iblock_element_1", "ix_iblock_element_4", "ix_iblock_element_3", "ix_iblock_element_code", "ix_iblock_element_openregion_3", "idx_b_iblock_element_ACTIVE", "idx_b_iblock_element_WF_STATUS_ID" ], "key_length": "3,4,5,5", "index_merge": { "intersect": { "range": { "key": "idx_b_iblock_element_ACTIVE", "used_key_parts": ["ACTIVE"] }, "range": { "key": "ix_iblock_element_openregion_3", "used_key_parts": ["IBLOCK_ID"] }, "range": { "key": "ix_iblock_element_3", "used_key_parts": ["WF_PARENT_ELEMENT_ID"] }, "range": { "key": "idx_b_iblock_element_WF_STATUS_ID", "used_key_parts": ["WF_STATUS_ID"] } } }, "rows": 23529, "filtered": 75.001, "attached_condition": "((BE.WF_STATUS_ID = 1) and (BE.IBLOCK_ID = '2') and (BE.ACTIVE = 'Y') and isnull(BE.WF_PARENT_ELEMENT_ID))" }, "table": { "table_name": "B", "access_type": "eq_ref", "possible_keys": ["PRIMARY", "b_iblock_LID_IDX_openregion"], "key": "PRIMARY", "key_length": "4", "used_key_parts": ["ID"], "ref": ["letters.BE.IBLOCK_ID"], "rows": 1, "filtered": 100 }, "table": { "table_name": "b_iblock_site", "access_type": "eq_ref", "possible_keys": ["PRIMARY", "idx_b_iblock_site_SITE_ID"], "key": "PRIMARY", "key_length": "10", "used_key_parts": ["IBLOCK_ID", "SITE_ID"], "ref": ["letters.BE.IBLOCK_ID", "const"], "rows": 1, "filtered": 100, "attached_condition": "(b_iblock_site.SITE_ID = 's2')", "using_index": true }, "table": { "table_name": "L", "access_type": "ALL", "possible_keys": ["PRIMARY"], "rows": 1, "filtered": 100, "attached_condition": "(L.LID = B.LID)" } } } } } Вернем поля, уберем один join на таблицу b_lang (к слову в ней только одна запись) Запрос выполняется 1.3 секунды.... Код: plsql 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.
План запроса { "query_block": { "select_id": 1, "read_sorted_file": { "filesort": { "table": { "table_name": "BE", "access_type": "index_merge", "possible_keys": [ "ix_iblock_element_1", "ix_iblock_element_4", "ix_iblock_element_3", "ix_iblock_element_code", "ix_iblock_element_openregion_3", "idx_b_iblock_element_ACTIVE", "idx_b_iblock_element_WF_STATUS_ID" ], "key_length": "3,4,5,5", "index_merge": { "intersect": { "range": { "key": "idx_b_iblock_element_ACTIVE", "used_key_parts": ["ACTIVE"] }, "range": { "key": "ix_iblock_element_openregion_3", "used_key_parts": ["IBLOCK_ID"] }, "range": { "key": "ix_iblock_element_3", "used_key_parts": ["WF_PARENT_ELEMENT_ID"] }, "range": { "key": "idx_b_iblock_element_WF_STATUS_ID", "used_key_parts": ["WF_STATUS_ID"] } } }, "rows": 23529, "filtered": 75.001, "attached_condition": "((BE.WF_STATUS_ID = 1) and (BE.IBLOCK_ID = '2') and (BE.ACTIVE = 'Y') and isnull(BE.WF_PARENT_ELEMENT_ID))" } } }, "table": { "table_name": "b_iblock_site", "access_type": "eq_ref", "possible_keys": ["PRIMARY", "idx_b_iblock_site_SITE_ID"], "key": "PRIMARY", "key_length": "10", "used_key_parts": ["IBLOCK_ID", "SITE_ID"], "ref": ["letters.BE.IBLOCK_ID", "const"], "rows": 1, "filtered": 100, "attached_condition": "(b_iblock_site.SITE_ID = 's2')", "using_index": true }, "table": { "table_name": "B", "access_type": "eq_ref", "possible_keys": ["PRIMARY"], "key": "PRIMARY", "key_length": "4", "used_key_parts": ["ID"], "ref": ["letters.BE.IBLOCK_ID"], "rows": 1, "filtered": 100 } } } Вернем как было... уберем сортировку время вполнения 0.093 секунды Код: plsql 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.
План запроса { "query_block": { "select_id": 1, "table": { "table_name": "L", "access_type": "ALL", "possible_keys": ["PRIMARY"], "rows": 1, "filtered": 100 }, "table": { "table_name": "BE", "access_type": "index_merge", "possible_keys": [ "ix_iblock_element_1", "ix_iblock_element_4", "ix_iblock_element_3", "ix_iblock_element_code", "ix_iblock_element_openregion_3", "idx_b_iblock_element_ACTIVE", "idx_b_iblock_element_WF_STATUS_ID" ], "key_length": "3,4,5,5", "index_merge": { "intersect": { "range": { "key": "idx_b_iblock_element_ACTIVE", "used_key_parts": ["ACTIVE"] }, "range": { "key": "ix_iblock_element_openregion_3", "used_key_parts": ["IBLOCK_ID"] }, "range": { "key": "ix_iblock_element_3", "used_key_parts": ["WF_PARENT_ELEMENT_ID"] }, "range": { "key": "idx_b_iblock_element_WF_STATUS_ID", "used_key_parts": ["WF_STATUS_ID"] } } }, "rows": 23530, "filtered": 75.002, "attached_condition": "((BE.WF_STATUS_ID = 1) and (BE.IBLOCK_ID = '2') and (BE.ACTIVE = 'Y') and isnull(BE.WF_PARENT_ELEMENT_ID))" }, "table": { "table_name": "b_iblock_site", "access_type": "eq_ref", "possible_keys": ["PRIMARY", "idx_b_iblock_site_SITE_ID"], "key": "PRIMARY", "key_length": "10", "used_key_parts": ["IBLOCK_ID", "SITE_ID"], "ref": ["letters.BE.IBLOCK_ID", "const"], "rows": 1, "filtered": 100, "attached_condition": "(b_iblock_site.SITE_ID = 's2')", "using_index": true }, "table": { "table_name": "B", "access_type": "eq_ref", "possible_keys": ["PRIMARY", "b_iblock_LID_IDX_openregion"], "key": "PRIMARY", "key_length": "4", "used_key_parts": ["ID"], "ref": ["letters.BE.IBLOCK_ID"], "rows": 1, "filtered": 100, "attached_condition": "(B.LID = L.LID)" } } } В общем вопрос... чего может не хватать для выполнения исходного запроса быстро? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.04.2020, 13:16 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
Добавлю что запрос висит на стадии "Copying to tmp table" При этом mysql начинает много-много писать на диск. Выставил параметры max_heap_table_size = 8G tmp_table_size = 8G при том что общий объем базы 6.5G Изменений никаких. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 15:59 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
YurikGL Выставил параметры max_heap_table_size = 8G tmp_table_size = 8G ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 16:01 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
miksoft, Оперативки 16G Проверял применение параметров через workbench. Он показывает, что применяется все. Вообще скорость зависит от количества выбираемых записей. Добавляешь условие and BE.ID >500000 - 7 секунд выполняется and BE.ID >700000 - 5 секунд выполняется. На диск продолжает писать. Такое ощущение, что он вообще всегда на диск пишет. В смысле подобные запросы... М.б. из за того, что в одной из таблиц есть поле типа text... .но даже если это поле не выбирать (убрать из выборки) - ничего принциально не меняется. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 16:12 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
Я уж забыл как этих битриксовых монстров оптимизировать :( Лет 5 назад получалось... YurikGL Оперативки 16G YurikGL max_heap_table_size = 8G tmp_table_size = 8G Есть метод не пытаться сократить дисковые операции с временными таблицами, а дать MySQL-ю быстрый диск для этого. Как вариант - расположить /tmp в оперативной памяти. Да и всю базу хорошо бы на SSD положить. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 17:10 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
miksoft, Вот что нашел https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html some query conditions prevent the use of an in-memory temporary table, in which case the server uses an on-disk table instead: Presence of a BLOB or TEXT column in the table. However, the TempTable storage engine, which is the default storage engine for in-memory internal temporary tables in MySQL 8.0, supports binary large object types as of MySQL 8.0.13. See Internal Temporary Table Storage Engine. Потом прочитал что можно задействовать вместо размещения временных таблиц на диске возможности движка aria Выставил aria_pagecache_buffer_size = 1G Запись на диск прекратилась... При этом время выполнения запроса упало с 12 до 10 сек. Что совсем не густо... Т.е. на диск теперь ничего не пишет, но увеличение скорости не значительное. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 17:40 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
YurikGL Выставил aria_pagecache_buffer_size = 1G Судя по описанию , это аналог innodb_buffer_pool_size для InnoDB. Вряд ли актуально в вашем случае, если вы не используете движок Aria. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 18:20 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
miksoft, miksoft YurikGL Выставил aria_pagecache_buffer_size = 1G Судя по описанию , это аналог innodb_buffer_pool_size для InnoDB. Вряд ли актуально в вашем случае, если вы не используете движок Aria. Вот почему актуально. https://mariadb.com/kb/en/configuring-mariadb-for-optimal-performance/ Aria Storage Engine MariaDB uses by default the Aria storage engine for internal temporary files. If you have many temporary files, you should set aria_pagecache_buffer_size to a reasonably large value so that temporary overflow data is not flushed to disk. The default is 128M. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.04.2020, 11:13 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
YurikGL, Понял. Но сама схема странная - кэшировать в одном буфере то, что не влезло в другой... ... |
|||
:
Нравится:
Не нравится:
|
|||
27.04.2020, 11:34 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
miksoft YurikGL, Понял. Но сама схема странная - кэшировать в одном буфере то, что не влезло в другой... По ходу только с типами данных поиграться можно. Text и longtext исключать. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.04.2020, 11:54 |
|
Тормозит запрос на join с таблицей одной строкой.
|
|||
---|---|---|---|
#18+
YurikGL miksoft YurikGL, Понял. Но сама схема странная - кэшировать в одном буфере то, что не влезло в другой... По ходу только с типами данных поиграться можно. Text и longtext исключать. Еще есть такой вариант: miksoft расположить /tmp в оперативной памяти. Да и всю базу хорошо бы на SSD положить. Кстати, в самом Битриксе был советчик по оптимизации запросов. Пару раз он мне выдавал полезные советы. В нем не смотрели? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.04.2020, 12:07 |
|
|
start [/forum/topic.php?fid=47&fpage=22&tid=1828609]: |
0ms |
get settings: |
7ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
59ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
others: | 393ms |
total: | 540ms |
0 / 0 |