powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / Почему ораклисты так не любят MS SQL?
7 сообщений из 457, страница 19 из 19
Почему ораклисты так не любят MS SQL?
    #33399207
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerА каков самый оптимальный подход?
...
Для обеих связок?

Это очень сильно завист от запроса. Например, сравним:

Код: plaintext
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.
SELECT
 *
FROM
  tblProducts P
  INNER JOIN tblProdNomenclature N ON
  P.colProductID = N.colProductID
  INNER JOIN tblSpecifications S ON
  N.colProductID = S.colProductID

  |--Merge Join(Inner Join, MERGE:([N].[colProductID])=([S].[colProductID]), RESIDUAL:([N].[colProductID]=[S].[colProductID]))
       |--Merge Join(Inner Join, MERGE:([N].[colProductID])=([P].[colProductID]), RESIDUAL:([P].[colProductID]=[N].[colProductID]))
       |    |--Clustered Index Scan(OBJECT:([data].[dbo].[tblProdNomenclature].[PK_tblProdNomenclature] AS [N]), ORDERED FORWARD)
       |    |--Clustered Index Scan(OBJECT:([data].[dbo].[tblProducts].[PK_tblProducts] AS [P]), ORDERED FORWARD)
       |--Clustered Index Scan(OBJECT:([data].[dbo].[tblSpecifications].[PK_tblSpecifications] AS [S]), ORDERED FORWARD)

SELECT
 *
FROM
  tblProducts P
  INNER JOIN tblProdNomenclature N ON
  P.colProductID = N.colProductID
  INNER JOIN tblSpecifications S ON
  N.colProductID = S.colProductID
WHERE
  N.colRailTypeID =  1 

  |--Merge Join(Inner Join, MERGE:([N].[colProductID])=([S].[colProductID]), RESIDUAL:([N].[colProductID]=[S].[colProductID]))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([N].[colProductID]) WITH PREFETCH)
       |    |--Clustered Index Scan(OBJECT:([data].[dbo].[tblProdNomenclature].[PK_tblProdNomenclature] AS [N]),  WHERE:([N].[colRailTypeID]=1) ORDERED FORWARD)
       |    |--Clustered Index Seek(OBJECT:([data].[dbo].[tblProducts].[PK_tblProducts] AS [P]), SEEK:([P].[colProductID]=[N].[colProductID]) ORDERED FORWARD)
       |--Clustered Index Scan(OBJECT:([data].[dbo].[tblSpecifications].[PK_tblSpecifications] AS [S]), ORDERED FORWARD)

Т.е. Merge Join эффективен, когда объем объединяемых данных велик и они могут получены пресортированными, например из существующего индекса. Сам смысл Merge Join - получение строки из одного пресортированного набора и сравнение его с другим пресортированным набором.

Nested Loops эффективен в случаи, когда один из наборов велик, по сравнению с другим набором, причем последний индексирован.

Т.е. при запросах, возвращающие большие результирующие наборы эффективнее Merge (или Hash) джоины, для "маленьких" запросов Nested Loops.

Аналогичное поведение и для запросов по схеме "звезда".

Код: plaintext
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.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
DECLARE @DepartmentID int, @DocTypeID int
SELECT tblDocuments.colDocumentID,
           tblDocuments.colPeriod,
           tblDocuments.colTaskID,
           tblDocuments.colDocumentTypeID,
           tblDocuments.colDocDate,
           tblDocuments.colDocNumber,
           tblDocuments.colDocCheck,
           tblOperationsType.colOperationName,
           colFigurant = CAST((case when tblDocuments.colSupplier IS NOT NULL then
                                 usv_ContragentsList.colFullContrName
                               when tblDocuments.colRecipient IS NOT NULL then
                                 usv_ContragentsList1.colFullContrName
                               when tblDocuments.colContrDepartmentID IS NOT NULL then
                                 usv_DepartmentsList.colDepartmentCode
           end) AS varchar( 255 )),
           tblDocuments.colDocumentSum,
           tblDocumentsType.colDocName
    FROM tblDocuments
         INNER JOIN tblOperationsType ON
         tblDocuments.colOperationCode = tblOperationsType.colOperationCode
         INNER JOIN tblDocumentsType ON
         tblDocuments.colDocumentTypeID = tblDocumentsType.colDocumentTypeID
         INNER JOIN usv_ContragentsList ON
         tblDocuments.colSupplier = usv_ContragentsList.colContragentID
         INNER JOIN usv_ContragentsList usv_ContragentsList1 ON
         tblDocuments.colRecipient = usv_ContragentsList1.colContragentID
         INNER JOIN usv_DepartmentsList ON
         tblDocuments.colContrDepartmentID = usv_DepartmentsList.colDepartmentID
    WHERE 
          (tblDocuments.colTaskID =  1 ) AND
          (tblDocuments.colDepartmentID = @DepartmentID) AND
          (tblDocuments.colDocumentTypeID = @DocTypeID)
    ORDER BY tblDocuments.colDocDate DESC

  |--Compute Scalar(DEFINE:([Expr1016]=Convert(If 1 then ([tblTowns].[colTownName]+' - '+[tblContragents].[colContragentName]) else If 1 then ([tblTowns].[colTownName]+' - '+[tblContragents].[colContragentName]) else If 1 then Convert((substring([tblDepart
       |--Nested Loops(Inner Join, OUTER REFERENCES:([tblContragents].[colTownID]))
            |--Bookmark Lookup(BOOKMARK:([Bmk1006]), OBJECT:([data].[dbo].[tblContragents]))
            |    |--Nested Loops(Inner Join, OUTER REFERENCES:([tblDocuments].[colSupplier]) WITH PREFETCH)
            |         |--Nested Loops(Inner Join, OUTER REFERENCES:([tblContragents].[colTownID]))
            |         |    |--Bookmark Lookup(BOOKMARK:([Bmk1008]), OBJECT:([data].[dbo].[tblContragents]))
            |         |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([tblDocuments].[colRecipient]) WITH PREFETCH)
            |         |    |         |--Nested Loops(Inner Join, OUTER REFERENCES:([tblDocuments].[colContrDepartmentID]))
            |         |    |         |    |--Bookmark Lookup(BOOKMARK:([Bmk1002]), OBJECT:([data].[dbo].[tblOperationsType]))
            |         |    |         |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([tblDocuments].[colOperationCode]))
            |         |    |         |    |         |--Nested Loops(Inner Join)
            |         |    |         |    |         |    |--Index Seek(OBJECT:([data].[dbo].[tblDocumentsType].[PK_tblDocumentsType]), SEEK:([tblDocumentsType].[colDocumentTypeID]=[@DocTypeID]) ORDERED FORWARD)
            |         |    |         |    |         |    |--Sort(ORDER BY:([tblDocuments].[colDocDate] DESC))
            |         |    |         |    |         |         |--Filter(WHERE:([tblDocuments].[colTaskID]=1))
            |         |    |         |    |         |              |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([data].[dbo].[tblDocuments]))
            |         |    |         |    |         |                   |--Hash Match(Inner Join, HASH:([Bmk1000])=([Bmk1000]), RESIDUAL:([Bmk1000]=[Bmk1000]))
            |         |    |         |    |         |                        |--Index Seek(OBJECT:([data].[dbo].[tblDocuments].[IX_tblDocuments_5]), SEEK:([tblDocuments].[colDepartmentID]=[@DepartmentID]) ORDERED FORWARD)
            |         |    |         |    |         |                        |--Index Seek(OBJECT:([data].[dbo].[tblDocuments].[IX_tblDocuments_9]), SEEK:([tblDocuments].[colDocumentTypeID]=[@DocTypeID]) ORDERED FORWARD)
            |         |    |         |    |         |--Index Seek(OBJECT:([data].[dbo].[tblOperationsType].[PK_tblOperationsType]), SEEK:([tblOperationsType].[colOperationCode]=[tblDocuments].[colOperationCode]) ORDERED FORWARD)
            |         |    |         |    |--Clustered Index Seek(OBJECT:([data].[dbo].[tblDepartments].[PK_tblDepartments]), SEEK:([tblDepartments].[colDepartmentID]=[tblDocuments].[colContrDepartmentID]) ORDERED FORWARD)
            |         |    |         |--Index Seek(OBJECT:([data].[dbo].[tblContragents].[PK_tblContragents]), SEEK:([tblContragents].[colContragentID]=[tblDocuments].[colRecipient]) ORDERED FORWARD)
            |         |    |--Clustered Index Seek(OBJECT:([data].[dbo].[tblTowns].[PK_tblTowns]), SEEK:([tblTowns].[colTownID]=[tblContragents].[colTownID]) ORDERED FORWARD)
            |         |--Index Seek(OBJECT:([data].[dbo].[tblContragents].[PK_tblContragents]), SEEK:([tblContragents].[colContragentID]=[tblDocuments].[colSupplier]) ORDERED FORWARD)
            |--Clustered Index Seek(OBJECT:([data].[dbo].[tblTowns].[PK_tblTowns]), SEEK:([tblTowns].[colTownID]=[tblContragents].[colTownID]) ORDERED FORWARD)

SELECT tblDocuments.colDocumentID,
           tblDocuments.colPeriod,
           tblDocuments.colTaskID,
           tblDocuments.colDocumentTypeID,
           tblDocuments.colDocDate,
           tblDocuments.colDocNumber,
           tblDocuments.colDocCheck,
           tblOperationsType.colOperationName,
           colFigurant = CAST((case when tblDocuments.colSupplier IS NOT NULL then
                                 usv_ContragentsList.colFullContrName
                               when tblDocuments.colRecipient IS NOT NULL then
                                 usv_ContragentsList1.colFullContrName
                               when tblDocuments.colContrDepartmentID IS NOT NULL then
                                 usv_DepartmentsList.colDepartmentCode
           end) AS varchar( 255 )),
           tblDocuments.colDocumentSum,
           tblDocumentsType.colDocName
    FROM tblDocuments
         INNER JOIN tblOperationsType ON
         tblDocuments.colOperationCode = tblOperationsType.colOperationCode
         INNER JOIN tblDocumentsType ON
         tblDocuments.colDocumentTypeID = tblDocumentsType.colDocumentTypeID
         INNER JOIN usv_ContragentsList ON
         tblDocuments.colSupplier = usv_ContragentsList.colContragentID
         INNER JOIN usv_ContragentsList usv_ContragentsList1 ON
         tblDocuments.colRecipient = usv_ContragentsList1.colContragentID
         INNER JOIN usv_DepartmentsList ON
         tblDocuments.colContrDepartmentID = usv_DepartmentsList.colDepartmentID
    ORDER BY tblDocuments.colDocDate DESC

 |--Sort(ORDER BY:([tblDocuments].[colDocDate] DESC))
       |--Compute Scalar(DEFINE:([Expr1016]=Convert(If 1 then ([tblTowns].[colTownName]+' - '+[tblContragents].[colContragentName]) else If 1 then ([tblTowns].[colTownName]+' - '+[tblContragents].[colContragentName]) else If 1 then Convert((substring([tblD
            |--Hash Match(Inner Join, HASH:([tblDocumentsType].[colDocumentTypeID])=([tblDocuments].[colDocumentTypeID]))
                 |--Index Scan(OBJECT:([data].[dbo].[tblDocumentsType].[PK_tblDocumentsType]))
                 |--Hash Match(Inner Join, HASH:([tblOperationsType].[colOperationCode])=([tblDocuments].[colOperationCode]), RESIDUAL:([tblDocuments].[colOperationCode]=[tblOperationsType].[colOperationCode]))
                      |--Table Scan(OBJECT:([data].[dbo].[tblOperationsType]))
                      |--Hash Match(Inner Join, HASH:([tblDepartments].[colDepartmentID])=([tblDocuments].[colContrDepartmentID]), RESIDUAL:([tblDocuments].[colContrDepartmentID]=[tblDepartments].[colDepartmentID]))
                           |--Clustered Index Scan(OBJECT:([data].[dbo].[tblDepartments].[PK_tblDepartments]))
                           |--Hash Match(Inner Join, HASH:([tblTowns].[colTownID])=([tblContragents].[colTownID]))
                                |--Index Scan(OBJECT:([data].[dbo].[tblTowns].[IX_tblTownsByRegions]))
                                |--Hash Match(Inner Join, HASH:([tblContragents].[colContragentID])=([tblDocuments].[colSupplier]), RESIDUAL:([tblContragents].[colContragentID]=[tblDocuments].[colSupplier]))
                                     |--Clustered Index Scan(OBJECT:([data].[dbo].[tblContragents].[IX_tblContragentsByName]))
                                     |--Hash Match(Inner Join, HASH:([tblContragents].[colContragentID])=([tblDocuments].[colRecipient]), RESIDUAL:([tblContragents].[colContragentID]=[tblDocuments].[colRecipient]))
                                          |--Hash Match(Inner Join, HASH:([tblTowns].[colTownID])=([tblContragents].[colTownID]))
                                          |    |--Index Scan(OBJECT:([data].[dbo].[tblTowns].[IX_tblTownsByRegions]))
                                          |    |--Clustered Index Scan(OBJECT:([data].[dbo].[tblContragents].[IX_tblContragentsByName]))
                                          |--Table Scan(OBJECT:([data].[dbo].[tblDocuments]))
...
Рейтинг: 0 / 0
Почему ораклисты так не любят MS SQL?
    #33429354
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спорил на днях с поклонником mssql по поводу постраничного вывода.
Так я делаю в Oracle:
Код:
1.
2.
select t.id 
 from (select id,rownum r from tmp where rownum < 500000) t 
 where t.r > 499950

Есть конечно и другие варианты, но все, что я видел, это вариации на тему.
В mssql я слышал это как-то проще пишется. Интересно знать, где быстрей будет получен результат, в mssql или Oracle, в предположении, что мощности сервера совпадают и в таблице 1-2 миллиона строк.
Задаю в эту тему, т.к. тут вроде есть люди, знающие обе СУБД.
...
Рейтинг: 0 / 0
Почему ораклисты так не любят MS SQL?
    #33430012
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 SeaGate

MS SQL не имеет (доступного разработчику) аналога Oracleовского rownum. Возможные варианты "постраничной выборки" приведены здесь: FAQ

На счет быстрее при одинаковой мощности... Лично я не проверял... Но варианты на MS SQL с использованием допю таблиц, IMHO, будут медленнее, чем прямая выборка из таблиц в Oracle.
...
Рейтинг: 0 / 0
Почему ораклисты так не любят MS SQL?
    #33430209
Ц4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ц4
Гость
Уже есть ровнамбер :)

SQL Server 2005 Books Online

ROW_NUMBER (Transact-SQL)
ROW_NUMBER ( ) OVER ( [ <partition_by_clause> ] <order_by_clause> )
...
Рейтинг: 0 / 0
Почему ораклисты так не любят MS SQL?
    #33430250
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Ц4

Согласен, в свой пост забыл добавить, что все эти варианты до Юконовские. ;)
...
Рейтинг: 0 / 0
Почему ораклисты так не любят MS SQL?
    #33430502
aZm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ц4Уже есть ровнамбер :)

SQL Server 2005 Books Online

ROW_NUMBER (Transact-SQL)
ROW_NUMBER ( ) OVER ( [ <partition_by_clause> ] <order_by_clause> )

аналитическая функа row_number() не есть аналог rownum :)
...
Рейтинг: 0 / 0
Почему ораклисты так не любят MS SQL?
    #33477724
Фотография Anton Demidov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aZmаналитическая функа row_number() не есть аналог rownum :)
На DB2 for Linux/UNIX/Windows эта функция и аналитическая, если используется с ORDER BY/PARTITION BY классами, либо аналог Оракловского rownum как частный случай. Подозреваю, что здесь тоже самое.

P.S.
На AS/400 DB2 её всё ещё нет
...
Рейтинг: 0 / 0
7 сообщений из 457, страница 19 из 19
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / Почему ораклисты так не любят MS SQL?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]