Задний план:
У нас есть приложение, которое активно использует базу данных SQL Server 2008. Мы пытаемся оптимизировать это приложение. Он был однопоточным, и мы заметили при ведении журнала / профилировании приложения, что самым большим узким местом были операции чтения / записи db. Некоторые звонки занимали до 100 мсек, что для нас слишком долго. Среди других оптимизаций мы выделили некоторые из этих вызовов в отдельный поток. Только благодаря этому изменению мы наблюдаем значительное улучшение времени обработки (код почти такой же, только некоторые были перемещены в другой поток)
Вопрос:
Предполагая, что время, затрачиваемое на выполнение кода в памяти, незначительно, я мог бы предположить, что выполнение некоторых операций чтения / записи в другом потоке не приведет к увеличению производительности. Я чувствую, что если бы SQL Server просто ставил запросы в очередь, чтение / запись в любом случае не могло бы происходить параллельно, поэтому время обработки было бы одинаковым. Это не вариант.
Мне интересно, как SQL Server обрабатывает два одновременных запроса (любую комбинацию чтения / записи) из разных потоков. Может ли он как-то выполнять их одновременно?
Таким образом, я бы предположил, что общее время запросов Query1 + Query2, вызываемых один за другим, будет аналогично одновременному вызову Query1 + Query2.
Это работает на двухъядерном сервере.
SQL Server - это многопользовательская база данных. В первую очередь он предназначен для обработки нескольких одновременных запросов.
В идеале два запроса, которые принимают A + B при последовательном выполнении, будут принимать MAX (A, B) при одновременном выполнении.
Чтобы предотвратить чтение или запись поврежденных данных, SQL Server использует Сделки и Блокировка. В дополнение к этому, приложения также могут управлять параллелизмом (оптимистичный, например).
Я думаю, что Дэвид Б. дал хороший ответ, но я просто собираюсь немного расширить его на примере.
Допустим, у вас есть две таблицы в вашей базе данных, Table_A и Table_B. Сервер имеет несколько процессоров. Кроме того, дисковая подсистема помещает каждую таблицу на отдельный диск / LUN / шпиндель (какова бы ни была правильная терминология, я не большой специалист по оборудованию). Кроме того, на сервере есть несколько сетевых карт.
Если два пользователя имеют доступ к базе данных, и один хочет писать в Table_A, а другой хочет читать из Table_B, то, надеюсь, вы можете увидеть, как запросы могут поступать одновременно на разные сетевые карты, обрабатываться одновременно разными процессорами / ядрами и вводом-выводом. активность может происходить одновременно на разных дисках.
В реальном мире редко бывает так просто. У вас обычно есть узкие места в одной или нескольких из этих областей, в зависимости от вашего оборудования и того, как используется приложение. Кроме того, если оба пользователя пытаются получить доступ к одним и тем же строкам в одной таблице, это может вызвать узкое место в ресурсах. Итак, в реальной жизни есть люди, которые проводят большую часть своего времени, пытаясь найти, какие ресурсы вызывают эти узкие места для приложения, и избавиться от этих узких мест. По крайней мере, обычно некоторые области, где вещи могут обрабатываться параллельно.
Ваш вопрос подразумевает, что до улучшений доступ к SQL был последовательным, то есть последующие запросы выполнялись один за другим, в том же соединении, в одном потоке кода.
Перемещение логики на отдельные потоки вызовет два различных эффекта: во-первых, ваш код больше не нужно ждать завершения каждого запроса, прежде чем продолжить, а во-вторых, SQL-запросы будут распараллелены (в определенной степени), что позволит SQL-серверу оптимизировать доступ к файлам данных - что намного, намного лучше, чем когда-либо мог бы ваш код быть.
Предполагая, что код состоит не только из чистых вызовов SQL, первые могут иметь такое же большое влияние, как и вторые.