Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Най-ефективният начин за ИЗБИРАНЕ на редове, КЪДЕТО СЪЩЕСТВУВА ИДЕНТИФИКАТОРЪТ ВЪВ втора таблица

Резюме:

Изпълних всяка заявка по 10 пъти, използвайки по-долу набор от тестови данни..

  1. Много голям набор от резултати на подзаявка (100 000 реда)
  2. Дублирани редове
  3. Нулеви редове

За всички горни сценарии и двата IN и EXISTS изпълнени по идентичен начин.

Малко информация за база данни Performance V3 използвани за тестване.20000 клиенти, имащи 1000000 поръчки, така че всеки клиент се дублира на случаен принцип (в диапазон от 10 до 100) в таблицата с поръчки.

Разходи за изпълнение, време:
По-долу е екранна снимка на двете изпълнявани заявки. Наблюдавайте относителната цена на всяка заявка.

Разходи за памет:
Предоставянето на памет за двете заявки също е същото.. Принудих MDOP 1, за да не ги прехвърля към TEMPDB..

CPU време, чете:

За съществува:

Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 1, logical reads 109, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 1, logical reads 3855, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 469 ms,  elapsed time = 595 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

За IN:

(20000 row(s) affected)
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 1, logical reads 109, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 1, logical reads 3855, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 547 ms,  elapsed time = 669 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

Във всеки случай оптимизаторът е достатъчно умен, за да пренареди заявките.

Склонен съм да използвам EXISTS само че (мое мнение). Един случай на употреба за използване на EXISTS е, когато не искате да върнете втора таблица с резултати.

Актуализация според заявки от Мартин Смит:

Изпълних заявките по-долу, за да намеря най-ефективния начин за получаване на редове от първата таблица, за която има препратка във втората таблица.

SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid   

SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid

SELECT *
FROM Customers C
WHERE EXISTS(SELECT 1 FROM Orders o WHERE o.custid = c.custid)

SELECT *
FROM Customers c
WHERE custid IN (SELECT custid FROM Orders)

Всички горни заявки споделят една и съща цена с изключение на 2-ро INNER JOIN , планът е същият за останалото.

Разрешение за памет:
Тази заявка

SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid 

изисква се предоставяне на памет от

Тази заявка

SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid 

изисква се предоставена памет от ..

CPU време, четене:
За заявка:

SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid   

(20000 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 48, logical reads 1344, physical reads 96, read-ahead reads 1248, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 5, logical reads 3929, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 5, logical reads 322, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 1453 ms,  elapsed time = 781 ms.

За заявка:

SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid

(20000 row(s) affected)
Table 'Customers'. Scan count 5, logical reads 322, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 5, logical reads 3929, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 1499 ms,  elapsed time = 403 ms.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server:Msg 102, ниво 15, състояние 1, ред 2 Неправилен синтаксис близо до '='

  2. Как да свържа тези двете заедно? Varchar guid и guid тип и двата първични ключа

  3. Разрешаване на специални знаци SQL Server 2008

  4. Брой Винаги връща -1 SQL Server. ASP.NET C#

  5. Защо използването на OPENQUERY на локален сървър е лошо?