Click here to Skip to main content
14,452,069 members
Rate this:
Please Sign up or sign in to vote.
See more:
i have the following query that takes more that 4 minutes to excute is there any other way to rewrite that query not that billsDetails table contains 100k record and Billtable contains 10k record


BillDetails table structure

BillDetailsID bigint not null "PK"
productID bigint null,
billID bigint null
BillType tinyint not null

BillsOperations table
BillID bigint not null "Pk"
ParentID bigint null "self relationship"
IsPermitted bit not null
BillType tinyint not null

SELECT * FROM (
SELECT 
b.BillID, b.Code,b.BillType,  dbo.Fn_BillNameByType(b.BillType) AS BillTypeName ,
(SELECT COUNT(BillDetailID) FROM dbo.BillsDetailsOperations WHERE BillID= b.BillID)   AS OriginalCount,


(
SELECT COUNT(DISTINCT ProductID) FROM dbo.BillsDetailsOperations
WHERE BillID IN (
SELECT BillID FROM dbo.BillsOperations WHERE ParentID = b.BillID AND BillType IN (9,10)))   AS PermittedCount

FROM dbo.BillsOperations  AS b
WHERE b.IsPermitted = 1 and b.BillType NOT IN (5,8,9,10)) AS detailsTbl
WHERE (detailsTbl.OriginalCount < detailsTbl.PermittedCount) OR (detailsTbl.OriginalCount > detailsTbl.PermittedCount) 


What I have tried:

i have tried to create group by but not working as i want
Posted
Updated 26-Sep-17 10:53am
v2
Comments
itsmypassion 25-Sep-17 7:01am
   
Please specify table structure.
TheSniper105 25-Sep-17 7:06am
   
i did
FranzBe 25-Sep-17 7:11am
   
Did you already check the 'Include actual execution plan' option and have a look at the results?
TheSniper105 25-Sep-17 7:43am
   
it takes much time when enable that option
Jörgen Andersson 27-Sep-17 4:57am
   
Just curious.
You accepted my solution so it must have worked.
How much faster did it get?
TheSniper105 28-Sep-17 0:22am
   
it is executed in 00:00:31 faster than the query in question and i found another solution i accept your answer because it gives me a key to make query faster (join instead of sub query) i found solution that executes in 00:00:00 :D
Jörgen Andersson 28-Sep-17 4:36am
   
Glad to help.
Rate this:
Please Sign up or sign in to vote.

Solution 1

Hi

First of all in your case i would make the BillDetails.BillId Foreign Key.

and if i understud you correct this is my solution.

CREATE TABLE #BillsOperations (	BillID  [bigint], ParentID  [bigint] null,IsPermitted  [bigint] NULL,BillType  [bigint] NULL);
CREATE TABLE #BillDetails (	BillDetailsID   [bigint], productID   [bigint],billID   [bigint] NULL,BillType [bigint] NULL);
CREATE TABLE #BillType (ID   [bigint], descr nvarchar(100));
insert into #BillType (ID, descr) values (9,'INVOICE');
insert into #BillType (ID, descr) values (1,'CREDITNOTE');

insert into #BillsOperations (BillID, ParentID,IsPermitted,BillType) values (1,null,1,9);
insert into #BillsOperations (BillID, ParentID,IsPermitted,BillType) values (2,null,1,9);
insert into #BillsOperations (BillID, ParentID,IsPermitted,BillType) values (3,null,1,1);

insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (1,1,1,9);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (2,2,1,9);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (3,3,1,9);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (4,4,1,9);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (5,1,2,9);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (6,1,2,9);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (7,2,2,9);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (8,3,2,9);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (9,1,3,1);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (10,2,3,1);
insert into #BillDetails (BillDetailsID, productID,billID,BillType) values (11,1,3,1);

select * from (select 
a.BillID, a.BillType,  c.descr AS BillTypeName , count(*) AS OriginalCount,
case when a.BillType IN (9,10) then COUNT(DISTINCT b.ProductID) else 0 end AS PermittedCount

from #BillsOperations a inner join #BillDetails b on a.BillID=b.billID inner join #BillType c on a.BillType=c.ID
group by a.BillID, a.BillType,  c.descr) x
--WHERE (OriginalCount < PermittedCount) OR (OriginalCount > PermittedCount) 


drop table #BillsOperations;
drop table #BillDetails;
drop table #BillType;


Have a nice day
   
Comments
TheSniper105 26-Sep-17 0:38am
   
not same query as i want
Rate this:
Please Sign up or sign in to vote.

Solution 2

First of all and most important, you need an index on BillDetails
CREATE NONCLUSTERED INDEX BillDetails_BillID_IX ON BillDetails (BillID) INCLUDE (productID)
And possibly also one on ParentID.

Secondly, avoid correlated subqueries as much as possible. Use joins instead.
Try this:
WITH j AS (
    SELECT  bo.ParentID
           ,bdp.productID
    FROM    dbo.BillsDetailsOperations bdp
    JOIN    dbo.BillsOperations bo ON bo.BillID = bdp.BillID
    WHERE   bo.BillType IN (9,10)
    )
,detailsTbl as (
    SELECT  b.BillID
           ,b.Code
           ,b.BillType
           ,dbo.Fn_BillNameByType(b.BillType) AS BillTypeName
           ,COUNT(bd.BillDetailID) AS OriginalCount
           ,COUNT(DISTINCT ProductID) AS PermittedCount
    FROM    dbo.BillsOperations  AS b
    LEFT JOIN   dbo.BillsDetailsOperations bd ON bd.BillID = b.BillID
    LEFT JOIN   j ON j.ParentID = b.BillID
    WHERE   b.IsPermitted = 1
        AND b.BillType NOT IN (5,8,9,10)
    GROUP BY b.BillID
           ,b.Code
           ,b.BillType
    )
SELECT  *
FROM    detailsTbl
WHERE   detailsTbl.OriginalCount != detailsTbl.PermittedCount 
   
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100