简体   繁体   中英

SQL Server optimize query that have subquery

I use SQL Server and have a query with low performance. My query is like below:

Select * 
from ... 
Where exists (Select * From ... Where ...)  

The execution time of above query is about 8 minute. if I use following format for this query, it run about 3 second.

declare @T table(Columns)
Insert into @T(columns)
Select *
From ...
Where ...

Select *
from ...
Where Exists (Select * From @T)

I can't use second format, because I use Entity Framework and it create query in first format. How can I do in order to have high performance with first query structure.

Edit 1 I use Entity Framework 6

Also I can't use stored procedure, because I have a lots of parameters in order to filter my data in my application.

Edit 2 This is the actual query:

SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[MasterID] AS [MasterID], 
    [Project1].[Date] AS [Date], 
    [Project1].[DateOnly] AS [DateOnly], 
    [Project1].[SalesCompanyFinancialPeriodID] AS [SalesCompanyFinancialPeriodID], 
    [Project1].[Number] AS [Number], 
    [Project1].[Description] AS [Description], 
    [Project1].[FormTypeID] AS [FormTypeID], 
    [Project1].[ProcessTypeID] AS [ProcessTypeID], 
    [Project1].[SalesCompanyID] AS [SalesCompanyID], 
    [Project1].[FinancialPeriodId] AS [FinancialPeriodId], 
    [Project1].[ParentMasterID] AS [ParentMasterID], 
    [Project1].[CustomerID] AS [CustomerID], 
    [Project1].[RecievedDate] AS [RecievedDate], 
    [Project1].[SalesBranchID] AS [SalesBranchID], 
    [Project1].[SellerID] AS [SellerID], 
    [Project1].[IsCompanyIntercourse] AS [IsCompanyIntercourse], 
    [Project1].[C2] AS [C2], 
    [Project1].[C3] AS [C3], 
    [Project1].[C4] AS [C4], 
    [Project1].[C5] AS [C5], 
    [Project1].[C6] AS [C6], 
    [Project1].[C7] AS [C7], 
    [Project1].[C8] AS [C8], 
    [Project1].[C9] AS [C9], 
    [Project1].[C10] AS [C10]
    FROM ( SELECT 
        [Extent1].[MasterID] AS [MasterID], 
        [Extent1].[CustomerID] AS [CustomerID], 
        [Extent1].[RecievedDate] AS [RecievedDate], 
        [Extent1].[SalesBranchID] AS [SalesBranchID], 
        [Extent1].[SellerID] AS [SellerID], 
        [Extent1].[IsCompanyIntercourse] AS [IsCompanyIntercourse], 
        [Extent2].[Date] AS [Date], 
        [Extent2].[DateOnly] AS [DateOnly], 
        [Extent2].[SalesCompanyFinancialPeriodID] AS [SalesCompanyFinancialPeriodID], 
        [Extent2].[Number] AS [Number], 
        [Extent2].[Description] AS [Description], 
        [Extent2].[FormTypeID] AS [FormTypeID], 
        [Extent2].[ProcessTypeID] AS [ProcessTypeID], 
        [Extent2].[SalesCompanyID] AS [SalesCompanyID], 
        [Extent2].[FinancialPeriodId] AS [FinancialPeriodId], 
        [Extent2].[ParentMasterID] AS [ParentMasterID], 
        '0X0X' AS [C1], 
        CAST(NULL AS int) AS [C2], 
        CAST(NULL AS int) AS [C3], 
        CAST(NULL AS int) AS [C4], 
        CAST(NULL AS bit) AS [C5], 
        CAST(NULL AS decimal(18,2)) AS [C6], 
        CAST(NULL AS int) AS [C7], 
        CAST(NULL AS int) AS [C8], 
        CAST(NULL AS int) AS [C9], 
        CAST(NULL AS int) AS [C10], 
        [Extent3].[FinancialPeriodID] AS [FinancialPeriodID1]
        FROM   [SAL].[Invoice] AS [Extent1]
        INNER JOIN [SAM].[Master] AS [Extent2] ON [Extent1].[MasterID] = [Extent2].[MasterID]
        INNER JOIN [ORG].[SalesCompanyFinancialPeriod] AS [Extent3] ON [Extent2].[SalesCompanyFinancialPeriodID] = [Extent3].[SalesCompanyFinancialPeriodID]
    )  AS [Project1]
    WHERE (10 = [Project1].[FinancialPeriodID1]) AND (13852 = [Project1].[SalesCompanyID]) AND ([Project1].[DateOnly] <= convert(datetime2, '2014-09-09 00:00:00.0000000', 121)) AND (convert(datetime2, '2014-09-07 00:00:00.0000000', 121) <=  CAST(  CAST( [Project1].[DateOnly] AS datetime2) AS datetime2)) AND (13852 = [Project1].[SalesCompanyID]) 
    AND ( EXISTS (SELECT 
        1 AS [C1]
        FROM   (SELECT [Extent4].[OrderMasterID] AS [OrderMasterID], [Extent5].[MasterID] AS [MasterID1]
            FROM        [SAL].[InvoiceDetail] AS [Extent4]
            INNER JOIN [SAM].[Detail] AS [Extent5] ON [Extent4].[DetailID] = [Extent5].[DetailID]
            LEFT OUTER JOIN [SAL].[Order] AS [Extent6] ON [Extent4].[OrderMasterID] = [Extent6].[MasterID]
            LEFT OUTER JOIN [SAL].[SalesBranch] AS [Extent7] ON [Extent6].[SalesBranchID] = [Extent7].[SalesBranchID]
            INNER JOIN [SAL].[SalesBranch] AS [Extent8] ON [Extent6].[SalesBranchID] = [Extent8].[SalesBranchID]
            LEFT OUTER JOIN [SAL].[Order] AS [Extent9] ON [Extent4].[OrderMasterID] = [Extent9].[MasterID]
            INNER JOIN [SAL].[Order] AS [Extent10] ON [Extent4].[OrderMasterID] = [Extent10].[MasterID]
            LEFT OUTER JOIN [SAL].[Order] AS [Extent11] ON [Extent4].[OrderMasterID] = [Extent11].[MasterID]
            WHERE ([Extent7].[SalesScopeID] IN (43893, 43900)) AND ([Extent8].[SalesScopeID] IS NOT NULL) AND ([Extent9].[SalesBranchID] IN (77017, 43063, 43029, 43021)) AND ([Extent10].[SalesBranchID] IS NOT NULL) AND ([Extent11].[SellerID] IN (42768, 50552, 15904, 15090, 15717, 16063, 43109, 43110, 43113, 43114, 43118, 43120, 43121, 43123, 43124, 43125, 43126, 43127, 43129, 43130, 43131, 43132, 43133, 43134, 43136, 43137, 43138, 43141, 43147, 43152, 43153, 43154, 43160, 43168, 43178, 43179, 43184, 43185, 43186, 43187, 43189, 43209, 43211, 43215, 43218, 43223, 43235, 43242, 43248, 43249, 43250, 43251, 43252, 43261, 43269, 43278, 43283, 43298, 43308, 43313, 43316, 43325, 43328, 43329, 43337, 43356, 43360, 43384, 43385, 43394, 43400, 43415, 43418, 43424, 43425, 43428, 43434, 43441, 43518, 43532, 43546, 43548, 43549, 44359, 44368, 44490, 47035, 48849, 49139, 49140, 49153, 49156, 50212, 50422, 50423, 51023, 52158, 61908, 61909, 79146, 80261, 80466, 80734, 80735, 80983, 82822, 86309, 86436, 86578, 86825, 86879, 87120, 43149, 45166, 44366, 80233)) ) AS [Filter1]
        INNER JOIN [SAL].[Order] AS [Extent12] ON [Filter1].[OrderMasterID] = [Extent12].[MasterID]
        WHERE ([Extent12].[SellerID] IS NOT NULL) AND ([Project1].[MasterID] = [Filter1].[MasterID1])
    )) AND ([Project1].[FormTypeID] = 6) AND (6 IS NOT NULL)

Edit 3: this is the execution plan of my query:

在此处输入图片说明

I'm not a SQL Guru, but i think it's a very bad habit having subqueries; you should avoid this.

You can for example do your 2 subqueries first and dynamically build your final SQL query within the program. Or put some triggers on your tables on order to prepare the data for querying (create an easy-to-query extra table).

You may get better performance on the actual query if you check for missing indexes. You can try running this in SQL Management Studio and use the Display Estimated Execution Plan, this will then show whether you are potentially missing indexes on the linked tables, if it does then by clicking on the messages you can generate the SQL Code to create the indexes. Otherwise I think we may need to see the LINQ statement you are using to generate the said code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM