-- Логический порядок обработки операторов в SQL запросе --FROM --ON --JOIN --WHERE --GROUP BY --WITH CUBE или WITH ROLLUP --HAVING --SELECT --DISTINCT --ORDER BY --TOP -- Наш запрос из видео: SELECT C.CustomerID, E.BusinessEntityID FROM Sales.Customer AS C CROSS JOIN HumanResources.Employee AS E; --Отдельная выборка из первой таблицы: SELECT * FROM Sales.Customer; --Отдельная выборка из второй таблицы: SELECT * FROM HumanResources.Employee; --Текстовый формат плана выполнения запроса, который отображает преполагаемый план с полным набором информации SET SHOWPLAN_ALL ON GO SELECT * FROM sys.databases; --SET SHOWPLAN_ALL OFF --Текстовый формат плана выполнения запроса, который отображает преполагаемый план с ограниченным набором информации SET SHOWPLAN_TEXT ON GO SELECT * FROM sys.databases; --SET SHOWPLAN_TEXT OFF --Текстовый формат плана выполнения запроса, который отображает фактический план со всеми деталями SET STATISTICS PROFILE ON GO SELECT * FROM sys.databases; --SET STATISTICS PROFILE OFF --XML формат плана выполнения запроса, который отображает преполагаемый план SET SHOWPLAN_XML ON GO SELECT * FROM sys.databases; --SET SHOWPLAN_XML OFF --XML формат плана выполнения запроса, который отображает фактический план SET STATISTICS XML ON GO SELECT * FROM sys.databases; --SET STATISTICS XML OFF --Пример Nested Loops Joins SELECT SOH.OrderDate, SOD.OrderQty, SOD.ProductID, SOD.UnitPrice FROM Sales.SalesOrderDetail AS SOD JOIN Sales.SalesOrderHeader AS SOH ON SOH.SalesOrderID = SOD.SalesOrderID WHERE SOH.OrderDate BETWEEN '2013-07-01' AND '2013-07-05'; --поменять для теста '2013-07-05' на '2014-07-05' и будет merge join --Пример Merge Joins SELECT C.CustomerID, SOH.SalesOrderID FROM Sales.SalesOrderHeader AS SOH JOIN Sales.Customer AS C ON SOH.CustomerID = C.CustomerID; --Пример Hash Match Joins SELECT C.PersonID, C.AccountNumber, SOH.SalesOrderID FROM Sales.SalesOrderHeader AS SOH JOIN Sales.Customer AS C ON SOH.TerritoryID = C.TerritoryID WHERE C.AccountNumber LIKE '%067%'; --Создадим 2 таблицы на основе таблиц, в которых есть индексы: SELECT * INTO Sales.SalesOrderHeader1 FROM Sales.SalesOrderHeader; SELECT * INTO Sales.SalesOrderDetail1 FROM Sales.SalesOrderDetail; --Query Hints ("заставить" SQL Server выбрать тот или иной тип физического соединения, --для этого используем ключевое слово OPTION и в круглых скобках указываем название соединения) --Для исходного запроса по-умолчанию выбирается тип соединения Merge join --Но мы принудительно задаем Hash match join SELECT C.CustomerID, SOH.SalesOrderID FROM Sales.SalesOrderHeader AS SOH JOIN Sales.Customer AS C ON SOH.CustomerID = C.CustomerID OPTION (HASH JOIN) --Для исходного запроса по-умолчанию выбирается тип соединения Hash match join --Но мы принудительно задаем Nested Loops join SELECT SOH.CustomerID, SOH.SalesOrderID, SOD.ProductID FROM Sales.SalesOrderHeader1 SOH INNER JOIN Sales.SalesOrderDetail1 SOD ON SOH.SalesOrderID = SOD.SalesOrderID WHERE SOH.CustomerID = 29825 OPTION (LOOP JOIN) --Для исходного запроса по-умолчанию выбирается тип соединения Hash match join --Но мы принудительно задаем Merge join SELECT SOH.CustomerID, SOH.SalesOrderID, SOD.ProductID FROM Sales.SalesOrderHeader1 SOH INNER JOIN Sales.SalesOrderDetail1 SOD ON SOH.SalesOrderID = SOD.SalesOrderID WHERE SOH.CustomerID = 29825 OPTION (MERGE JOIN) --------------------------------------------------Индексы-------------------------------------------------- -- Посмотреть данные об индексах в sys.indexes: SELECT * FROM [master].[sys].[indexes]; --Создадим для теста новую базу данных: CREATE DATABASE schooldb; --Переключимся на эту базу данных: USE schooldb; --Создадим таблицу в этой базе данных: CREATE TABLE student ( ID INT PRIMARY KEY, Name VARCHAR(50) NOT NULL, Gender VARCHAR(50) NOT NULL, DOB datetime NOT NULL, TotalScore INT NOT NULL, City VARCHAR(50) NOT NULL ); --Чтобы увидеть все индексы в конкретной таблице, выполним хранимую процедуру sp_helpindex EXECUTE sp_helpindex student; --Наполним нашу таблицу тестовыми данными INSERT INTO student VALUES (6, 'Kate', 'Female', '03-JAN-1985', 500, 'Liverpool'), (2, 'Jon', 'Male', '02-FEB-1974', 545, 'Manchester'), (9, 'Wise', 'Male', '11-NOV-1987', 499, 'Manchester'), (3, 'Sara', 'Female', '07-MAR-1988', 600, 'Leeds'), (1, 'Jolly', 'Female', '12-JUN-1989', 500, 'London'), (4, 'Laura', 'Female', '22-DEC-1981', 400, 'Liverpool'), (7, 'Joseph', 'Male', '09-APR-1982', 643, 'London'), (5, 'Alan', 'Male', '29-JUL-1993', 500, 'London'), (8, 'Mice', 'Male', '16-AUG-1974', 543, 'Liverpool'), (10, 'Elis', 'Female', '28-OCT-1990', 400, 'Leeds'); --Сделаем выборку из нашей таблицы и посмотрим на результат: SELECT * FROM student; --Удалим автоматически созданный кластерный индекс вручную через графическое меню -- и создадим новый кластерный индекс CREATE CLUSTERED INDEX IX_tblStudent_Gender_Score ON student(gender ASC, TotalScore DESC); --Сделаем выборку из нашей таблицы и посмотрим на результат:: SELECT * FROM student; -- создадим некластерный индекс: CREATE NONCLUSTERED INDEX IX_tblStudent_Name ON student(name ASC); --Когда выполняется запрос к столбцу, по которому создается индекс, --база данных сначала переходит к индексу и ищет адрес соответствующей --строки в таблице. Затем он перейдет к адресу этой строки и получит другие значения столбца. --Переключимся на другую базу данных: USE AdventureWorks2019; --Создадим новую таблицу на базе таюлицы, у которой есть индексы: SELECT * INTO Person.Person2 FROM Person.Person; --Сделаем выборку из нашей исходной таблицы, где есть индексы: SELECT * FROM Person.Person WHERE BusinessEntityID = 1; --Сделаем выборку из нашей созданной таблицы, где нет индексов: SELECT * FROM Person.Person2 WHERE BusinessEntityID = 1; --Посмотрим информацию об индексах нашей новой созданной таблицы: SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('Person.Person2', 'U'); --Создадим некластерный индекс: CREATE NONCLUSTERED INDEX IX_Last_Name ON Person.Person2(LastName DESC); --Создадим кластерный индекс: CREATE CLUSTERED INDEX IX_BusinessEntityID ON Person.Person2(BusinessEntityID ASC); --Сделем запрос, в котором у нас будут содержаться столбец с некластерным индексом: SELECT LastName FROM Person.Person2 WHERE LastName = 'Ross'; --Сделем запрос, в котором у нас будут содержаться столбец с некластерным индексом и столбец без индекса: SELECT FirstName, LastName FROM Person.Person2 WHERE LastName = 'Ross'; --Сделем запрос, в котором у нас будут содержаться столбец с некластерным индексом и столбец без индекса, -- при этом у нас фильтр будет сразу по столбцу с кластерным индексом: SELECT FirstName, LastName FROM Person.Person2 WHERE BusinessEntityID = 1;