|
|
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Добрый время суток. Только начал изучать многопоточность, сейчас мне нужно делать INSERT в одну таблицу большим количеством потоков, так как очень большой объем данных. Использую Lazarus, SQL server 2014, прочитал что нужно создавать для каждого потока свои компоненты подключения и прочитал вики страницу по использованию потоков по паскалю. После этого сделал 2 потока и из метода Execute только вызываю одну и туже процедуру в которой идет обработка строк, создаются динамически компоненты подключения, в потоках указана 1 процедура в которой частями получаются данные с стороннего сервера, обрабатываются строки, происходит вставка INSERT SQL. В результате получаю ошибку RUNTIME 204, когда 1 поток, то все работает нормально. В процедуре вставки есть еще локальные строковые переменные процедуры (для будущей вставки) которые копируются из огромной строки и они в потоках не пересекаются, но SQL Insert дает сбой при 2 потоках и более. Привожу код, что мне надо сделать чтобы исправить ситуацию? Прошу ссылки на примеры использования баз данных в потоках и\или конкретные советы по задаче. Как правильно использовать переменные и компоненты в потоках - должны быть уникальные имена компонентов или 2 потока могут ссылаться на одну и туже внешнюю процедуру и данные не будут сбиваться (пример что будет если 2 потока ссылаюся на процедуру с sql_db:=tsqlquery.create(self) с разными запросами - будет ли это корректно работать? Потоки в программе только вставляют данные в одну таблицу, с интерфейсом не соприкасаются. Код: pascal 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 14:55 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Moneo Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. На вскидку: оба потока работают с одним участком памяти. ЗЫ. На какой строке возникает ошибка lazarus не показывает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 15:17 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Многопоточность нужна не для ускорения! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 15:19 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Ошибка при открытии SQL, перед вставкой идет открытие на проверку наличия ID в таблице, если нету, то вставляется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 15:31 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Еще и коннект на каждый чих стартует, когда достаточно при старте потока его создать, а при окончании уже уничтожить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 15:33 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Cobalt747, ну тогда поясните почему в итоге ускоряется обработка данынх ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 15:40 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
wadman, в каком месте он стартует на каждый чих. Расскажите как правильно в данном случае вставку в потоках делать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 15:41 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Мой главный вопрос - как избежать написание однотипного кода при потоках и как работать с запросами к одной таблице базы данных на вставку, обновление? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 15:43 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Может мне нужно создавать компоненты SQL в execute каждого потока отдельно, а потом их передать функции get_main_data2 в параметрах - это способствует разделению подключений к базе и не нужно будет передавать и обрабатывать кучу строк? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 15:48 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Moneo Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 16:49 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
А я бы посоветовал посмотреть на план исполнения в MSSQL, Профайлер что говорит? Про блокировки таблицы, про сам запрос. (может, HINT нужно добавить?) Разобраться, наконец, с блокировками. Transactionlog позырить... __________ ну и запроса INSERT/UPDATE не видно пока. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 18:28 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
для заливки данных есть bcp, в круйнем случае есть специальный интерфейс для быстрой заливки данных в таблицы, на память сейчас не вспомню но посмотрите доку на TLoader у SDAC, он его использует, в доке сказано через какой интерфейс загоняет. По итогу там десятки тысяч записей в секунду получаются потому что льются сразу данные в таблицу без всяких insert ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 20:40 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
энди, bcp Действительно хороша, но она ведь тупо игнорирует триггеры, ключи и пр. А ещё фигатень в журнале транзакций. Но если залить таблицу(ы) с нуля, - очень впечатляет!. Зато потом надо включить триггеры, констрейнты и перестроить индексы. На этом время и схомячится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 22:16 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Gator, Например, моя Собачья База весит всего 30 ГБ, и там всего две больший таблицы Dogs & Person + линк между ними. Reindex для меня - жесть! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 22:23 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Array DML ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 22:32 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Cobalt747Многопоточность нужна не для ускорения!А для чего ещё? Именно для ускорения обработки одних и тех же данных. Ну или совмещения обработки разных данных ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 22:36 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Dmitry ArefievArray DMLНасколько мои тупые мозги осознали, в MSSQL физически это реализуется через выборки/временные таблицы. В чём выгода? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 22:45 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Moneoсейчас мне нужно делать INSERT в одну таблицу большим количеством потоков, так как очень большой объем данных. как-то странно ты потоки используешь: из execute доп.потока вызываешь процедуры основного :) Может сделать примерно так? Код: pascal 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 22:55 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
GatorDmitry ArefievArray DMLНасколько мои тупые мозги осознали, в MSSQL физически это реализуется через выборки/временные таблицы. В чём выгода? В сокращении накладных расходов на один за одним вызовом. Можно и TVP - где-то быстрее (зависит, может быть и много). BCP - наибыстрейший, но с ним не спрашивай о консистентности :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 23:24 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Dmitry ArefievArray DML Дмитрий, ты сказуемое пропустил, как обычно.)) Однако, было бы очень любопытно, если бы кто-нибудь сравнил многопоточную вставку в MS SQL через Array DML и многопоточный же Bulk Inset посредством все того же Fire DAC. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2019, 23:56 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Dmitry Arefiev, И всё равно всё сводится к временным таблицам IMHO Допустим, загрузка данных в таблицы. Затратность навскидку Метод Данные КонсистентностьBCP 10%90%долгий реиндекс и т.п.TVP 99%1%индексы на пустых таблицах строятся моментально Т.е. исходные данные надо как-то формировать заранее, а затем их писать в таблицы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.04.2019, 00:12 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Moneo, вот ещё почитай https://docs.microsoft.com/ru-ru/sql/tools/bcp-utility?view=sql-server-2017 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.04.2019, 00:39 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Читать сюда отсюда и до обеда :) https://docs.microsoft.com/en-us/sql/connect/oledb/ole-db-interfaces/irowsetfastload-ole-db?view=sql-server-2017 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.04.2019, 10:18 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Док,спасибо за наводку и всем остальным за ссылки. Буду пробовать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.04.2019, 13:38 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Док, сделал так как вы говорили, но при получении большого числа страниц новые POST запросы валяться с ошибкой: Resultcode 0, Resultstring пусто - какая-то часть страниц получается хорошо, но большая часть сыпит ошибки, пробовал делать задержку в виде sleep, но не помогает. В коде идет получение страниц с сервера за 120 дней, в потоке получение кода страницы и сохранение в stringlist, потом txt. Объем каждой страницы от 200кб до 8мб. Скажите есть ли вообще смысл использовать потоки для выкачивания такого объема информации, ведь на сеть ограничение 100 мегабит и ошибки почему-то сыпит. Код: pascal 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. Код потоков: Код: pascal 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2019, 16:31 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Moneo, с сетевым протоколом не работал, деталей реализации подсказать не смогу. По коду: вот это Код: pascal 1. я бы завернул в Queue(PostMessage) или Synchronize(SendMessage). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2019, 21:27 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Moneo Код: pascal 1. 2. 3. 4. Зачем из потока показываете диалоговое окно?! Ошибки выводите в лог к примеру. Ну и заворачивайте использование экземпляров в блоки try-finally. Иначе при ошибках будут утечки памяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2019, 08:51 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Это все конечно хорошо, спасибо за советы, но может кто-то знает как в данном случае реализовать очередь потоков с пост запросами? Я ставлю 5 потоков по 30 раз с задержкой в 2 секунды между ними - тогда все отрабатывается на ура, но я хочу сделать это все как надо реализовав очередь и убрав не нужные простои в 2 секунды, но не знаю как. Кто подскажет? Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2019, 10:29 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Как только встречаются большие файлы я даже с таким количеством потоков и задержкой получаю ошибки, на один файл приходится до 8мб, но мое предположение состоит в том, что несколько потоков забивают сетевой канал и следующий пост запрос в потоке уже не может получить код страницы, так как канал сетевой забит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2019, 10:49 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
Moneo, забитый канал скорее приведет к ошибкам таймаута, а не просто пустой странице. сам сервер при нагрузке может тупить и возвращать что то не то. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2019, 11:13 |
|
||
|
Lazarus SQL многопоточность INSERT
|
|||
|---|---|---|---|
|
#18+
MoneoКто подскажет? В главном потоке любые циклы с задержкой будут приводить к "подвисаниям" UI, что воспринимается, как фризы и лаги. Отсюда не видно, по каким критериям ты контроллируешь, что ты успел выкачать на клиента удачно, а что - нет. В твоем случае я бы схематично сделал цикл внутри Execute доп.потока как-нибудь так: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. Повторюсь, я с синапсом никогда не работал, поэтому ничего дельного посоветовать не могу. Попробуй глянуть еще тут ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2019, 17:48 |
|
||
|
|

start [/forum/topic.php?all=1&fid=58&tid=2039558]: |
0ms |
get settings: |
7ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
151ms |
get topic data: |
6ms |
get forum data: |
1ms |
get page messages: |
33ms |
get tp. blocked users: |
1ms |
| others: | 227ms |
| total: | 439ms |

| 0 / 0 |
