|
|
|
Оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Всем доброго времени суток! Помогите пожалуйста оптимизировать запрос на INSERT. Есть таблица locations в которой поле location представляет собой полный адрес типа "Республика Бурятия Район Тункинский Село Кырен Улица Ленина Дом 156.". Из вне в формате csv приходят адреса разных подключений в таком формате. Так как регион и город в отдельное поле там вынести не могут, пришлось самому этим заниматься. В отдельных таблицах у меня есть список всех регионов и большинства городов. Написал две функции, которые для входной строки с полным адресом выводит один из имеющихся с БД городов либо регионов. Проблема в том, что эти функции я повесил на триггер BEFORE INSERT и когда я делаю INSERT IGNORE в таблицу locations (чтобы вставить только те адреса, которых еще нет в базе и для них вычислить город и регион), триггер вызывается для всех 3500 строк, из-за чего запрос длится около 50 секунд, хотя по факту ни одна новая строка не вставляется. Generated column использовать не могу, т.к. версия MySQL 5.6 Код: sql 1. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 20:49 |
|
||
|
Оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Pim.Проблема в том, что эти функции я повесил на триггер BEFORE INSERT и когда я делаю INSERT IGNORE в таблицу locations (чтобы вставить только те адреса, которых еще нет в базе и для них вычислить город и регион), триггер вызывается для всех 3500 строк, из-за чего запрос длится около 50 секунд, хотя по факту ни одна новая строка не вставляется. Это не страшно и вполне допустимо. [8]> (coerce (/ (/ 3500 50)) 'float) 0.014285714 14 милисекунд на запись. Нормально. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 23:50 |
|
||
|
Оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Pim., Хотя вот эту CREATE FUNCTION `get_city`(in_location VARCHAR(255)) RETURNS smallint(5) unsigned функцию можно и получше сделать, нужно уйти от перебора в цикле по курсору всех записей из cities и выборке нужной записи из cities одним запросом с использованием индекса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 23:57 |
|
||
|
Оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Pim., А зачем делать курсором и процедурой то, что можно сделать одним запросом? Что-то типа такого: Код: sql 1. 2. 3. 4. Это, правда, не избавит от фулскана таблицы cities, но хоть накладных расходов поменьше будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 00:02 |
|
||
|
Оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
MasterZiv, miksoft, Спасибо большое! Я что-то с дуру решил мыслить процедурным языком)) Переписал функции, но в триггере прописал селекты, ибо вызов функции накладывает лишнюю секунду. Хоть это и не принципиально, но глазу приятно. В итоге с 50 секунд, инсерт сократился до 2,6 секунд. Хоть это уже для меня и готовое решение проблемы, все же, нет ли у кого-нибудь идей, как избежать фулскана таблицы при инсерте? Вот, что получилось: Код: sql 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 02:33 |
|
||
|
|

start [/forum/topic.php?fid=47&fpage=112&tid=1832207]: |
0ms |
get settings: |
8ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
57ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
53ms |
get tp. blocked users: |
2ms |
| others: | 244ms |
| total: | 402ms |

| 0 / 0 |
