Related
I am working on a project that has multiple agents and members. Now I have to do the following (through a SQL Query):
Select agents and members under a Parent Agent who have made payments, in full (amounting to total of 430, i.e. 130+150+150) for 3 months.
Each Agent has n-number of members, so for each agent I need to check if all the members have paid their 3month dues.
If dues are paid, return the total member count agent wise for the parent agent.
I have tried the following query, but no luck:
CREATE TABLE [dbo].[SlipDetails](
[SlipDetailsID] [int] IDENTITY(1,1) NOT NULL,
[SlipID] [int] NULL,
[SlipNumber] [nvarchar](50) NULL,
[AgentID] [int] NULL,
[AgentName] [nvarchar](50) NULL,
[MemberID] [int] NULL,
[MemberName] [nvarchar](50) NULL,
[MonthID] [int] NULL,
[MonthAmount] [int] NULL,
[LateFine] [int] NULL,
[SubmittedDateByAgent] [datetime] NULL,
[ApprovedByAdmin] [nvarchar](1) NULL,
[ApprovedDate] [datetime] NULL,
[MonthName] [nvarchar](50) NULL,
[Blocked] [nvarchar](1) NULL,
CONSTRAINT [PK_SlipDetails] PRIMARY KEY CLUSTERED
(
[SlipDetailsID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[MemberMaster](
[MemberID] [int] IDENTITY(1,1) NOT NULL,
[MemberName] [nvarchar](50) NULL,
[MemberMobile] [varchar](50) NULL,
[MemberEmail] [nvarchar](50) NULL,
[MemberDOB] [nvarchar](50) NULL,
[MemberDOJ] [nvarchar](50) NULL,
[MemberGender] [nvarchar](50) NULL,
[MemberGenderID] [int] NULL,
[MemberAddress] [nvarchar](50) NULL,
[MemberPhoto] [nvarchar](50) NULL,
[IsFreeGift] [int] NULL,
[GiftID] [int] NULL,
[GiftName] [nvarchar](50) NULL,
[AgentID] [int] NULL,
[AgentName] [nvarchar](50) NULL,
[CardID] [int] NULL,
[CardNumber] [nvarchar](50) NULL,
[SID] [int] NULL,
[SName] [nvarchar](50) NULL,
[Custom1] [nvarchar](50) NULL,
[Custom2] [nvarchar](50) NULL,
[IsActive] [nvarchar](1) NULL,
[IsBlocked] [nvarchar](1) NULL,
CONSTRAINT [PK_MemberMaster] PRIMARY KEY CLUSTERED
(
[MemberID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[AgentMaster](
[AgentID] [int] IDENTITY(1,1) NOT NULL,
[AgentName] [nvarchar](50) NULL,
[Mobile] [nvarchar](50) NULL,
[AgentUserName] [nvarchar](50) NULL,
[AgentPassword] [nvarchar](50) NULL,
[IsActive] [nvarchar](1) NULL,
[ParentAgentID] [int] NULL,
[ParentAgentName] [nvarchar](50) NULL,
[BankName] [nvarchar](50) NULL,
[AccountHolderName] [nvarchar](50) NULL,
[IFSC] [nvarchar](50) NULL,
[BranchName] [nvarchar](50) NULL,
[AccountNo] [nvarchar](50) NULL,
[AgentPhoto] [nvarchar](50) NULL,
[DOJ] [datetime] NULL,
[SelectedInDraw] [nvarchar](1) NULL,
CONSTRAINT [PK_AgentMaster] PRIMARY KEY CLUSTERED
(
[AgentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Query:
SELECT COUNT(dbo.MemberMaster.MemberID) AS CMemberID
FROM dbo.SlipDetails
INNER JOIN dbo.MemberMaster ON dbo.SlipDetails.MemberID = dbo.MemberMaster.MemberID
WHERE dbo.MemberMaster.AgentID = 203
GROUP BY dbo.MemberMaster.AgentID,
dbo.SlipDetails.MonthAmount
HAVING(SUM(dbo.SlipDetails.MonthAmount) >= 430);
How do I get the Exact Count for the members under each agent? Any help would be great.
Select mm.AgentName,Count(mm.MemberID) as MemberCount from MemberMaster mm
INNER JOIN
(Select AgentID,MemberId from SlipDetails
group by AgentID,MemberID
having Sum(MonthAmount)>=430)sd
on sd.AgentID=mm.AgentID and sd.MemberID=mm.MemberID
Group by mm.AgentID, mm.AgentName
or even:
Select am.AgentName,MemberCount from AgentMaster am
inner join
(Select mm.AgentID,Count(mm.MemberID) as MemberCount from MemberMaster mm
INNER JOIN
(Select AgentID,MemberId from SlipDetails
group by AgentID,MemberID
having Sum(MonthAmount)>=430)sd
on sd.AgentID=mm.AgentID and sd.MemberID=mm.MemberID
Group by mm.AgentID)mm1
on am.AgentID=mm1.AgentID
Try this
WITH SlipDetails_ttl as (
Select st.MemberID, sum(MonthAmount) as MonthAmount_ttl
from SlipDetails as st
group by st.MemberID
having sum(MonthAmount)>=430
)
Select am.AgentID, count(stt.MemberID)
From SlipDetails_ttl as stt
join MemberMaster as mm on mm.MemberID = stt.MemberID
join AgentMaster as am on mm.AgentID = am.AgentID
group by am.AgentID
Give this a try:
SELECT agt.AgentID, COUNT(*)
FROM dbo.AgentMaster agt -- Get all agents
INNER JOIN dbo.MemberMaster mbr ON agt.AgentID = mbr.AgentID -- Get each agents' members
INNER JOIN dbo.SlipDetails slp ON mbr.MemberID = slp.MemberID -- Get payment details for members
GROUP BY agt.AgentID
HAVING(SUM(slp.MonthAmount)) = 430 -- Only return members that have paid 430
A few assumptions/notes:
only looks at each agent's immediate members (not recursive, one level only)
does not factor in 3-month constraint, only checks that 430 has been paid per member
I am using tablediff.exe to compare two SQL tables, on two servers one is local and the other is remote.
My first table is Table1 (380,000 records)
My second Table is Table2 (290,000 records)
When I compare local Table1 to remote Table1 it takes about 6 minutes .
When I compare local Table2 to remote Table2 it takes about forever and no result (Table2 has less records than Table1)
I deleted a column of type image from Table2, but the problem still there.
What may be the problem ?
NOTE: TABLE2 Structure
[ID] [varchar](10) NOT NULL,
[Title] [nvarchar](10) NULL,
[FName] [nvarchar](255) NULL,
[MName] [nvarchar](25) NULL,
[LName] [nvarchar](25) NULL,
[MotherName] [nvarchar](25) NULL,
[DOB] [datetime] NULL,
[BirthPlace] [nvarchar](50) NULL,
[Gender] [varchar](1) NULL,
[MaritalStatus] [nvarchar](25) NULL,
[ChildrenNo] [varchar](50) NULL,
[Occupation] [nvarchar](25) NULL,
[NationalityID] [varchar](3) NULL,
[Address] [nvarchar](255) NULL,
[Telephone] [varchar](20) NULL,
[Mobile] [varchar](20) NULL,
[Email] [varchar](50) NULL,
[BloodGroup] [varchar](3) NULL,
[RecieveSMS] [bit] NULL,
[FileNo] [nvarchar](250) NULL,
[PrimaryPhysician] [varchar](10) NULL,
[IqamaID] [varchar](10) NULL,
[EmergencyContactName] [nvarchar](50) NULL,
[EmergencyContactRelation] [nvarchar](50) NULL,
[EmergencyContactNo] [nvarchar](50) NULL,
[ProfilePicture] [image] NULL,
[Status] [bit] NULL,
[SecondaryTelNo] [varchar](20) NULL,
[SecondaryMobileNo] [varchar](20) NULL,
[Notes] [nvarchar](255) NULL,
[BankID] [varchar](10) NULL,
[IBANNo] [nvarchar](50) NULL,
[isWalkIn] [bit] NULL CONSTRAINT [DF_Patients_isWalkIn] DEFAULT ((0)),
[AR_FName] [nvarchar](255) NULL,
[AR_MName] [nvarchar](25) NULL,
[AR_LName] [nvarchar](25) NULL,
[AR_MotherName] [nvarchar](25) NULL,
[isVIP] [bit] NULL,
[FirstVisitDate] [varchar](255) NULL,
[EmploymentID] [varchar](20) NULL,
[ImagePath] [nvarchar](250) NULL,
[PatientLevel] [int] NOT NULL CONSTRAINT [DF_Patients_PatientLevel] DEFAULT ((1)),
CONSTRAINT [PK_Patients] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
i've been given a task to improve the below query because it's kinda slow.
SELECT 9 AS FieldCount,
A.AccountName AS Field1,
U.FullName AS Field2,
A.City AS Field3,
A.State AS Field4,
A.Zip5 AS Field5,
COUNT(DISTiNCT C.Contact_ID) AS Field6,
COUNT(DISTiNCT L.Lead_ID) AS Field7,
A.Account_ID AS Field8,
A.CreateDateTime AS Field9,
ROW_NUMBER() OVER (ORDER BY A.CreateDateTime DESC) As RowNum
FROM
dynamic_Account A
LEFT JOIN dynamic_Contact C
ON A.Account_ID = C.Account_ID
LEFT JOIN dynamic_Lead L
ON A.Account_ID = L.Account_ID,
static_List AS LS,
static_List AS LC,
static_User AS U
WHERE (A.Account_ID > 0)
AND (A.Source_ID = LS.List_ID)
AND (A.Category_ID = LC.List_ID)
AND (A.AccountSR01_ID = U.User_ID)
GROUP BY
AccountName,
LC.Title,
U.FullName,
A.City,
A.State,
A.Zip5,
A.Account_ID,
A.CreateDateTime
Can anyone please give me a pointer of how the joint can be improved or where to put the index? Thanks
EDIT:
Below is the create scripts of the tables that I generated from sql management studio.
dynamic_Account:
CREATE TABLE [dbo].[dynamic_Account](
[Account_ID] [int] IDENTITY(1,1) NOT NULL,
[RecordStatus] [int] NULL,
[AttributeList] [nvarchar](max) NULL,
[CreateUser_ID] [int] NULL,
[CreateDateTime] [datetime] NULL,
[ChangeUser_ID] [int] NULL,
[ChangeDateTime] [datetime] NULL,
[ViewUser_ID] [int] NULL,
[ViewDateTime] [datetime] NULL,
[InactiveFlag] [bit] NOT NULL,
[Source_ID] [int] NULL,
[Campaign_ID] [int] NULL,
[Comments] [nvarchar](max) NULL,
[Parent_ID] [int] NULL,
[Subsidiary_ID] [int] NULL,
[IndividualFlag] [bit] NOT NULL,
[AccountType] [nvarchar](50) NULL,
[AccountStage] [nvarchar](50) NULL,
[AccountName] [nvarchar](100) NULL,
[CompanyName] [nvarchar](100) NULL,
[Address1] [nvarchar](100) NULL,
[Address2] [nvarchar](100) NULL,
[Address3] [nvarchar](100) NULL,
[Address4] [nvarchar](100) NULL,
[City] [nvarchar](100) NULL,
[State] [nvarchar](100) NULL,
[PostalCode] [nvarchar](20) NULL,
[Zip5] [nvarchar](5) NULL,
[Zip4] [nvarchar](4) NULL,
[Country] [nvarchar](50) NULL,
[DoNotMailFlag] [bit] NOT NULL,
[TerritoryList] [nvarchar](255) NULL,
[PhoneNumber] [nvarchar](30) NULL,
[DoNotCallFlag] [bit] NOT NULL,
[FaxNumber] [nvarchar](30) NULL,
[Category_ID] [int] NULL,
[OtherNameList] [nvarchar](255) NULL,
[WebSite] [nvarchar](255) NULL,
[Geolocation] [nvarchar](100) NULL,
[OverrideTerritoryFlag] [bit] NOT NULL,
[AccountSR01_ID] [int] NULL,
[AccountSR02_ID] [int] NULL,
[AccountSR03_ID] [int] NULL,
[AccountSR04_ID] [int] NULL,
[AccountSR05_ID] [int] NULL,
[AccountSR06_ID] [int] NULL,
[AccountSR07_ID] [int] NULL,
[AccountSR08_ID] [int] NULL,
[AccountSR09_ID] [int] NULL,
[AccountSR10_ID] [int] NULL,
[AccountSR11_ID] [int] NULL,
[AccountSR12_ID] [int] NULL,
[AccountSR13_ID] [int] NULL,
[AccountSR14_ID] [int] NULL,
[AccountSR15_ID] [int] NULL,
[AnnualRevenue] [nvarchar](100) NULL,
[EmployeeCount] [nvarchar](100) NULL,
[BusinessDuration] [nvarchar](100) NULL,
[Custom_01] [nvarchar](255) NULL,
[Custom_02] [nvarchar](255) NULL,
[Custom_03] [nvarchar](255) NULL,
[Custom_04] [nvarchar](255) NULL,
[Custom_05] [nvarchar](255) NULL,
[Custom_06] [nvarchar](255) NULL,
[Custom_07] [nvarchar](255) NULL,
[Custom_08] [nvarchar](255) NULL,
[Custom_09] [nvarchar](255) NULL,
[Custom_10] [nvarchar](255) NULL,
[Custom_11] [nvarchar](255) NULL,
[Custom_12] [nvarchar](255) NULL,
[Custom_13] [nvarchar](255) NULL,
[Custom_14] [nvarchar](255) NULL,
[Custom_15] [nvarchar](255) NULL,
[Custom_16] [nvarchar](255) NULL,
[Custom_17] [nvarchar](255) NULL,
[Custom_18] [nvarchar](255) NULL,
[Custom_19] [nvarchar](255) NULL,
[Custom_20] [nvarchar](255) NULL,
CONSTRAINT [PK_dynamic_Account_1] PRIMARY KEY CLUSTERED
(
[Account_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
dynamic_Contact:
CREATE TABLE [dbo].[dynamic_Contact](
[Contact_ID] [int] IDENTITY(1,1) NOT NULL,
[RecordStatus] [int] NULL,
[AttributeList] [nvarchar](max) NULL,
[CreateUser_ID] [int] NULL,
[CreateDateTime] [datetime] NULL,
[ChangeUser_ID] [int] NULL,
[ChangeDateTime] [datetime] NULL,
[ViewUser_ID] [int] NULL,
[ViewDateTime] [datetime] NULL,
[InactiveFlag] [bit] NOT NULL,
[Source_ID] [int] NULL,
[Campaign_ID] [int] NULL,
[Comments] [nvarchar](max) NULL,
[Subsidiary_ID] [int] NULL,
[Account_ID] [int] NULL,
[ContactName] [nvarchar](50) NULL,
[Salutation] [nvarchar](10) NULL,
[FirstName] [nvarchar](50) NULL,
[MiddleInitial] [nvarchar](10) NULL,
[LastName] [nvarchar](50) NULL,
[Department] [nvarchar](255) NULL,
[JobTitle] [nvarchar](255) NULL,
[RoleList] [nvarchar](255) NULL,
[DoNotMailFlag] [bit] NOT NULL,
[WorkPhoneNumber] [nvarchar](30) NULL,
[DoNotCallWorkFlag] [bit] NOT NULL,
[CellPhoneNumber] [nvarchar](30) NULL,
[DoNotCallCellFlag] [bit] NOT NULL,
[HomePhoneNumber] [nvarchar](30) NULL,
[DoNotCallHomeFlag] [bit] NOT NULL,
[EmailAddress] [nvarchar](100) NULL,
[DoNotEmailFlag] [bit] NOT NULL,
[AltEmailAddress] [nvarchar](100) NULL,
[DoNotEmailAltFlag] [bit] NOT NULL,
[ProductInterestList] [nvarchar](255) NULL,
[Custom_01] [nvarchar](255) NULL,
[Custom_02] [nvarchar](255) NULL,
[Custom_03] [nvarchar](255) NULL,
[Custom_04] [nvarchar](255) NULL,
[Custom_05] [nvarchar](255) NULL,
[Custom_06] [nvarchar](255) NULL,
[Custom_07] [nvarchar](255) NULL,
[Custom_08] [nvarchar](255) NULL,
[Custom_09] [nvarchar](255) NULL,
[Custom_10] [nvarchar](255) NULL,
[Custom_11] [nvarchar](255) NULL,
[Custom_12] [nvarchar](255) NULL,
[ProductInterestListOld] [nvarchar](255) NULL,
CONSTRAINT [PK_dynamic_Contact] PRIMARY KEY CLUSTERED
(
[Contact_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
dynamic_Lead:
CREATE TABLE [dbo].[dynamic_Lead](
[Lead_ID] [int] IDENTITY(1,1) NOT NULL,
[RecordStatus] [int] NULL,
[AttributeList] [nvarchar](max) NULL,
[CreateUser_ID] [int] NULL,
[CreateDateTime] [datetime] NULL,
[ChangeUser_ID] [int] NULL,
[ChangeDateTime] [datetime] NULL,
[ViewUser_ID] [int] NULL,
[ViewDateTime] [datetime] NULL,
[Source_ID] [int] NULL,
[Campaign_ID] [int] NULL,
[Comments] [nvarchar](max) NULL,
[Subsidiary_ID] [int] NULL,
[Contact_ID] [int] NULL,
[Account_ID] [int] NULL,
[LeadDateTime] [datetime] NULL,
[Description] [nvarchar](255) NULL,
[Details] [nvarchar](max) NULL,
[OverrideTerritoryFlag] [bit] NULL,
[SalesRep_ID] [int] NULL,
[SalesGroup_ID] [int] NULL,
[LeadQuality_ID] [int] NULL,
[LeadStage_ID] [int] NULL,
[LeadStatus_ID] [int] NULL,
[ActivityStatus_ID] [int] NULL,
[DisqualifiedReason_ID] [int] NULL,
[ProductInterestList] [nvarchar](255) NULL,
[Score] [int] NULL,
[Custom_01] [nvarchar](255) NULL,
[Custom_02] [nvarchar](255) NULL,
[Custom_03] [nvarchar](255) NULL,
[Custom_04] [nvarchar](255) NULL,
[Custom_05] [nvarchar](255) NULL,
[Custom_06] [nvarchar](255) NULL,
[Custom_07] [nvarchar](255) NULL,
[Custom_08] [nvarchar](255) NULL,
[Custom_09] [nvarchar](255) NULL,
[Custom_10] [nvarchar](255) NULL,
[Custom_11] [nvarchar](255) NULL,
[Custom_12] [nvarchar](255) NULL,
[ProductInterestListOld] [nvarchar](255) NULL,
CONSTRAINT [PK_dynamic_Lead] PRIMARY KEY CLUSTERED
(
[Lead_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
static_List:
CREATE TABLE [dbo].[static_List](
[List_ID] [int] IDENTITY(1,1) NOT NULL,
[RecordStatus] [int] NULL,
[AttributeList] [ntext] NULL,
[CreateUser_ID] [int] NULL,
[CreateDateTime] [datetime] NULL,
[ChangeUser_ID] [int] NULL,
[ChangeDateTime] [datetime] NULL,
[InactiveFlag] [bit] NULL,
[ListName] [nvarchar](100) NULL,
[Title] [nvarchar](100) NULL,
[Parent_ID] [int] NULL,
[DisplayIndex] [int] NULL,
[DefaultFlag] [bit] NULL,
[External_ID] [nvarchar](255) NULL,
[Custom_01] [nvarchar](255) NULL,
[Custom_02] [nvarchar](255) NULL,
[Custom_03] [nvarchar](255) NULL,
[Custom_04] [nvarchar](255) NULL,
[Custom_05] [nvarchar](255) NULL,
[Custom_06] [nvarchar](255) NULL,
[Custom_07] [nvarchar](255) NULL,
[Custom_08] [nvarchar](255) NULL,
[Custom_09] [nvarchar](255) NULL,
[Custom_10] [nvarchar](255) NULL,
[Custom_11] [nvarchar](255) NULL,
[Custom_12] [nvarchar](255) NULL,
[Custom_13] [nvarchar](255) NULL,
[Custom_14] [nvarchar](255) NULL,
[Custom_15] [nvarchar](255) NULL,
[Custom_16] [nvarchar](255) NULL,
[Custom_17] [nvarchar](255) NULL,
[Custom_18] [nvarchar](255) NULL,
[Custom_19] [nvarchar](255) NULL,
[Custom_20] [nvarchar](255) NULL,
CONSTRAINT [PK_tmp_static_List] PRIMARY KEY CLUSTERED
(
[List_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
static_User:
CREATE TABLE [dbo].[static_User](
[User_ID] [int] IDENTITY(1,1) NOT NULL,
[RecordStatus] [int] NULL,
[AttributeList] [nvarchar](max) NULL,
[CreateUser_ID] [int] NULL,
[CreateDateTime] [datetime] NULL,
[ChangeUser_ID] [int] NULL,
[ChangeDateTime] [datetime] NULL,
[InactiveFlag] [bit] NOT NULL,
[Username] [nvarchar](100) NULL,
[EmailAddress] [nvarchar](150) NULL,
[LegalName] [nvarchar](100) NULL,
[FullName] [nvarchar](100) NULL,
[FirstName] [nvarchar](100) NULL,
[LastName] [nvarchar](100) NULL,
[DisplayName] [nvarchar](100) NULL,
[NickName] [nvarchar](100) NULL,
[CellPhoneNumber] [nvarchar](100) NULL,
[WorkPhoneNumber] [nvarchar](100) NULL,
[FaxNumber] [nvarchar](100) NULL,
[JobTitle] [nvarchar](100) NULL,
[Department] [nvarchar](100) NULL,
[OfficeName] [nvarchar](100) NULL,
[Address1] [nvarchar](100) NULL,
[Address2] [nvarchar](100) NULL,
[Address3] [nvarchar](100) NULL,
[City] [nvarchar](100) NULL,
[State] [nvarchar](100) NULL,
[Zip] [nvarchar](100) NULL,
[Country] [nvarchar](100) NULL,
[LastAccess] [datetime] NULL,
[Custom_01] [nvarchar](255) NULL,
[Custom_02] [nvarchar](255) NULL,
[Custom_03] [nvarchar](255) NULL,
[Custom_04] [nvarchar](255) NULL,
[Custom_05] [nvarchar](255) NULL,
[Custom_06] [nvarchar](255) NULL,
[Custom_07] [nvarchar](255) NULL,
[Custom_08] [nvarchar](255) NULL,
[Custom_09] [nvarchar](255) NULL,
[Custom_10] [nvarchar](255) NULL,
[Custom_11] [nvarchar](255) NULL,
[Custom_12] [nvarchar](255) NULL,
CONSTRAINT [PK_dbo_static_User] PRIMARY KEY CLUSTERED
(
[User_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON
Row Counts:
dynamic_Account: 180,000 rows
dynamic_Contact: 310,000 rows
dynamic_Lead: 130,000 rows
static_List: 1300 rows
static_User: 250 rows
I currently have no index on any table.
Since your results do NOT include anything from static_List, removing static_List from your FROM clause and using an EXISTS or IN in the WHERE clause will probably help. Also, you should be consistent with how you join your tables. Finally, since you don't show anything from the static_List table, including it in your GROUP BY clause doesn't make sense.
You might be able to add indices that speed up your process, but changing your query as follows will probably have the largest impact:
SELECT 9 AS FieldCount,
A.AccountName AS Field1,
U.FullName AS Field2,
A.City AS Field3,
A.State AS Field4,
A.Zip5 AS Field5,
COUNT(DISTiNCT C.Contact_ID) AS Field6,
COUNT(DISTiNCT L.Lead_ID) AS Field7,
A.Account_ID AS Field8,
A.CreateDateTime AS Field9,
ROW_NUMBER() OVER (ORDER BY A.CreateDateTime DESC) As RowNum
FROM
dynamic_Account A
LEFT JOIN dynamic_Contact C
ON A.Account_ID = C.Account_ID
LEFT JOIN dynamic_Lead L
ON A.Account_ID = L.Account_ID,
INNER JOIN static_User U ON A.AccountSR01_ID = U.User_ID
WHERE (A.Account_ID > 0)
AND EXISTS(SELECT 1 from static_List WHERE A.Category_ID = List_ID Or A.Source_ID = List_ID)
GROUP BY
AccountName,
U.FullName,
A.City,
A.State,
A.Zip5,
A.Account_ID,
A.CreateDateTime
Generally speaking, you want to add indexes on the following:
a) joins
b) order by columns
c) group by columns
If you understand what the database is doing, in each of those actions it has to:
a) sort the table to figure out which ones match
b) sort the table in the sequence is needed to return the result set
c) sort the table on what it is grouping by
Indexes and query optimization is a simple subject, but it can contain a lot of complexities.
Also, a primary key automatically creates a UNIQUE index (as a primary key is unique). So you do not need to index this, as long as the PK is there.
This should give you a good starting point.
In your case, I would add an index (the default type is "b-tree") to :
dynamic_contact (Account_ID)
dynamic_lead (Account_ID)
Hope this helps.
This looks like SQL Server to me.
The query returns 180,000 rows, so it will never be extremely fast.
I made few guesses/assumptions about relationships between the tables.
WITH
CTE_Contacts
AS
(
SELECT
dynamic_Contact.Account_ID
,COUNT(*) AS CountContacts
FROM dynamic_Contact
GROUP BY dynamic_Contact.Account_ID
)
,CTE_Leads
AS
(
SELECT
dynamic_Lead.Account_ID
,COUNT(*) AS CountLeads
FROM dynamic_Lead
GROUP BY dynamic_Lead.Account_ID
)
SELECT
9 AS FieldCount
,A.AccountName AS Field1
,U.FullName AS Field2
,A.City AS Field3
,A.State AS Field4
,A.Zip5 AS Field5
,ISNULL(CTE_Contacts.CountContacts, 0) AS Field6
,ISNULL(CTE_Leads.CountLeads, 0) AS Field7
,A.Account_ID AS Field8
,A.CreateDateTime AS Field9
,ROW_NUMBER() OVER (ORDER BY A.CreateDateTime DESC) As RowNum
FROM
dynamic_Account AS A
INNER JOIN static_User AS U ON U.User_ID = A.AccountSR01_ID
INNER JOIN static_List AS LS ON LS.List_ID = A.Source_ID
INNER JOIN static_List AS LC ON LC.List_ID = A.Category_ID
LEFT JOIN CTE_Contacts AS C ON C.Account_ID = A.Account_ID
LEFT JOIN CTE_Leads AS L ON L.Account_ID = A.Account_ID
WHERE
(A.Account_ID > 0)
;
Account_ID is not NULL and it is IDENTITY starting from 1, so all values should be positive, so there is no point having explicit filter Account_ID > 0. It doesn't make much sense to join to static_List, unless A.Source_ID and A.Category_ID can have values that don't exist in static_List (like NULL).
Create indexes
These are very important (even if you don't change the query itself):
dynamic_Contact.Account_ID
dynamic_Lead.Account_ID
These are no so important, but may be useful:
dynamic_Account.AccountSR01_ID
dynamic_Account.Source_ID
dynamic_Account.Category_ID
dynamic_Account.CreateDateTime
Create foreign keys
For all relations between the tables.
We have a table, which is partitioned through a date field into separate years.
There is a view over all of these tables (Call)
Schema is as follows:
CREATE TABLE [dbo].[Call_2015](
[calID] [uniqueidentifier] NOT NULL,
[calPackageID] [int] NULL,
[calClientID] [int] NULL,
[calStartDate] [datetime] NOT NULL,
[calEndDate] [datetime] NOT NULL,
[calTimeIn] [char](5) NULL,
[calTimeOut] [char](5) NULL,
[calMinutes] [smallint] NULL,
[calPreferredTimeIn] [char](5) NULL,
[calPreferredTimeOut] [char](5) NULL,
[calActualTimeIn] [char](5) NULL,
[calActualTimeOut] [char](5) NULL,
[calActualMinutes] [smallint] NULL,
[calConfirmed] [smallint] NULL,
[calCarerID] [int] NULL,
[calRepCarerID] [int] NULL,
[calOriginalCarerID] [int] NULL,
[calContractID] [int] NULL,
[calNeedID] [int] NULL,
[calMedicationID] [int] NULL,
[calFrequency] [smallint] NULL,
[calFromDate] [datetime] NULL,
[calWeekNo] [smallint] NULL,
[calAlert] [smallint] NULL,
[calNoLeave] [smallint] NULL,
[calTimeCritical] [smallint] NULL,
[calStatus] [smallint] NULL,
[calClientAwayReasonID] [int] NULL,
[calCarerAwayReasonID] [int] NULL,
[calOutsideShift] [smallint] NULL,
[calHistoryID] [int] NULL,
[calInvoiceID] [int] NULL,
[calWagesheetID] [int] NULL,
[calReasonID] [int] NULL,
[calCallConfirmID] [varchar](50) NULL,
[calCreated] [datetime] NULL,
[calUpdated] [datetime] NULL,
[calVariation] [int] NULL,
[calVariationUserID] [int] NULL,
[calException] [smallint] NULL,
[calRetained] [smallint] NULL,
[calDoubleUpID] [uniqueidentifier] NULL,
[calDoubleUpOrder] [smallint] NULL,
[calNeedCount] [smallint] NULL,
[calNoStay] [smallint] NULL,
[calCoverCarerID] [int] NULL,
[calPayAdjustment] [real] NULL,
[calChargeAdjustment] [real] NULL,
[calTeamID] [int] NULL,
[calExpenses] [money] NULL,
[calMileage] [real] NULL,
[calOverrideStatus] [smallint] NULL,
[calLocked] [smallint] NULL,
[calDriver] [smallint] NULL,
[calPostcode] [char](10) NULL,
[calDayCentreID] [int] NULL,
[calMustHaveCarer] [smallint] NULL,
[calRoleID] [int] NULL,
[calUnavailableCarerID] [int] NULL,
[calClientInformed] [smallint] NULL,
[calFamilyInformed] [smallint] NULL,
[calMonthlyDay] [smallint] NULL,
[calOriginalTimeIn] [char](5) NULL,
[calLeadCarer] [smallint] NULL,
[calCallTypeID] [int] NULL,
[calActualStartDate] [datetime] NULL,
[calActualEndDate] [datetime] NULL,
[Table_Year] [int] NOT NULL,
CONSTRAINT [PK_Call_2015] PRIMARY KEY CLUSTERED
(
[Table_Year] ASC,
[calID] ASC,
[calStartDate] ASC,
[calEndDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Call_2015] WITH CHECK ADD CONSTRAINT [CK_Call_Year_2015] CHECK (([Table_Year]=(2015)))
GO
ALTER TABLE [dbo].[Call_2015] CHECK CONSTRAINT [CK_Call_Year_2015]
GO
ALTER TABLE [dbo].[Call_2015] WITH CHECK ADD CONSTRAINT [CK_calStartDate_2015] CHECK (([calStartDate]>=CONVERT([datetime],'01 Jan 2015 00:00:00',(0)) AND [calStartDate]<=CONVERT([datetime],'31 DEC 2015 23:59:59',(0))))
GO
ALTER TABLE [dbo].[Call_2015] CHECK CONSTRAINT [CK_calStartDate_2015]
GO
ALTER TABLE [dbo].[Call_2015] ADD CONSTRAINT [DF_Call_2015_Table_Year] DEFAULT ((2015)) FOR [Table_Year]
GO
The update to the table is as follows:
UPDATE Call SET
calStartDate = CASE
WHEN calFrequency = 14 THEN dbo.funDate(#MonthlyDay, MONTH(calStartDate), YEAR(calStartDate))
WHEN calFrequency IN (15,16) THEN dbo.funMonthlyCallDate(calFrequency, #MonthlyDay, calStartDate)
ELSE DateAdd(d, #StartDay-1, (calStartDate - datepart(dw,calStartDate)+1))
END,
calEndDate = CASE
WHEN calFrequency = 14 THEN dbo.funDate(#MonthlyDay + #EndDay - #StartDay, MONTH(calStartDate), YEAR(calStartDate))
WHEN calFrequency IN (15,16) THEN DATEADD(D, #EndDay - #StartDay, dbo.funMonthlyCallDate(calFrequency, #MonthlyDay, calStartDate))
ELSE DateAdd(d, #StartDay-1+#DayCount, (calStartDate - datepart(dw,calStartDate)+1))
END,
calTimeIn = #TimeIn,
calTimeOut = #TimeOut,
calMinutes = #Minutes,
calMonthlyDay = #MonthlyDay,
calClientInformed = Null,
calFamilyInformed = Null
WHERE calPackageID = #PackageID
AND calClientID = #ClientID
AND calWeekNo = #WeekNo
AND (DatePart(dw, calStartDate) = #OriginalDay OR calFrequency IN (14,15,16))
AND calStartDate BETWEEN #StartDate AND #EndDate
AND (calInvoiceID = 0 OR calInvoiceID Is Null OR #InvoicesFinalised = 1)
AND (calWagesheetID = 0 OR calWagesheetID Is Null OR #WagesFinalised = 1)
AND (calLocked = 0 OR calLocked Is Null)
AND (Table_Year = YEAR(#StartDate)
OR Table_Year =YEAR(#EndDate))
The SP updates a batch of rows dependant of input into #StartDate and #EndDate (updates all rows with a calStartDate between the two)
The problem then comes with the execution plan. There are huge IO costs to the operation, and I've nailed it down to how SQL is dealing with the update.
Currently we have 20 of these tables; partitioned per year. Each update is causing an update of every single table's indexes, regardless of whether the table is actually touched by the update operation or not.
Execution Plan
Below this section it goes on to update, in the exact same manner, every table in the view.
I cannot see why this is, as I have specified the Table_Year (which the table is partitioned on) within the query text. Shouldn't SQL only update the necessary table?
I am executing the query on SQL server on hosting and it is taking 1 minute and 35 seconds. And the no, of rows of retrieval are 18000. Still it is taking too much time. Query is
select ID,
FirstName,
LastName,
Branch,
EnquiryID,
Course,
College,
Mobile,
ExamID,
EntranceID,
Entrance,
Venue,
RegNo,
VenueID,
Exam,
Gender,
row_number() over (partition by EnquiryID order by ID asc) as AttemptNO
from AGAM_View_AOPList
order by EnquiryID
TABLE SCHEMAS
CREATE TABLE [dbo].[AGAM_AceOFPace](
[ID] [int] IDENTITY(1,1) NOT NULL,
[EnquiryID] [int] NULL,
[FirstName] [nvarchar](100) NULL,
[MiddleName] [nvarchar](100) NULL,
[LastName] [nvarchar](100) NULL,
[BranchID] [int] NULL,
[Branch] [nvarchar](100) NULL,
[CourseID] [int] NULL,
[ExamID] [int] NULL,
[Exam] [nvarchar](200) NULL,
[EntranceID] [int] NULL,
[Entrance] [nvarchar](200) NULL,
[RegNo] [nvarchar](200) NULL,
[EntranceCode] [nvarchar](100) NULL,
[ExamDate] [nvarchar](50) NULL,
[UserID] [nvarchar](100) NULL,
[EntranceFees] [numeric](18, 2) NULL,
[VenueID] [int] NULL,
[Venue] [nvarchar](max) NULL,
[ChequeNumber] [nvarchar](50) NULL,
[Bank] [nvarchar](100) NULL,
[CreatedDate] [datetime] NULL,
CONSTRAINT [PK_AGAM_AceOFPace] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[AGAM_AceOFPace] WITH CHECK ADD CONSTRAINT [FK_AGAM_AceOFPace_AGAM_Inquiry] FOREIGN KEY([EnquiryID])
REFERENCES [dbo].[AGAM_Inquiry] ([ID])
GO
ALTER TABLE [dbo].[AGAM_AceOFPace] CHECK CONSTRAINT [FK_AGAM_AceOFPace_AGAM_Inquiry]
GO
SECOND TABLE
CREATE TABLE [dbo].[AGAM_Inquiry](
[ID] [int] IDENTITY(1,1) NOT NULL,
[RegNo] [nvarchar](200) NULL,
[BranchID] [int] NULL,
[Category] [nvarchar](100) NULL,
[CourseID] [int] NULL,
[EntranceFees] [numeric](18, 2) NULL,
[EntranceID] [int] NULL,
[UserID] [nvarchar](50) NULL,
[Status] [nvarchar](50) NULL,
[ReminderDate] [datetime] NULL,
[Reminder] [nvarchar](150) NULL,
[Mobile] [nvarchar](50) NULL,
[Email] [nvarchar](50) NULL,
[FirstName] [nvarchar](50) NULL,
[MiddleName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[Landline] [nvarchar](50) NULL,
[Address] [nvarchar](100) NULL,
[DOB] [datetime] NULL,
[Gender] [nvarchar](50) NULL,
[PfBatchTime] [nvarchar](50) NULL,
[SourceOfInquiry] [nvarchar](50) NULL,
[ExStudentID] [int] NULL,
[InquiryDate] [datetime] NULL,
[ReceiptNumber] [nvarchar](50) NULL,
[RawID] [int] NULL,
[Deleted] [int] NULL,
[CreatedBy] [nvarchar](50) NULL,
[CreatedDate] [datetime] NULL,
[LastModifiedBy] [nvarchar](50) NULL,
[LastModifiedDate] [datetime] NULL,
[College] [nvarchar](150) NULL,
[Qualification] [nvarchar](150) NULL,
[RptNo] [nvarchar](100) NULL,
CONSTRAINT [PK_AGAM_Inquiry] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[AGAM_Inquiry] WITH CHECK ADD CONSTRAINT [FK_AGAM_Inquiry_AGAM_Branch] FOREIGN KEY([BranchID])
REFERENCES [dbo].[AGAM_Branch] ([ID])
GO
ALTER TABLE [dbo].[AGAM_Inquiry] CHECK CONSTRAINT [FK_AGAM_Inquiry_AGAM_Branch]
GO
ALTER TABLE [dbo].[AGAM_Inquiry] WITH CHECK ADD CONSTRAINT [FK_AGAM_Inquiry_AGAM_Course] FOREIGN KEY([CourseID])
REFERENCES [dbo].[AGAM_Course] ([ID])
GO
ALTER TABLE [dbo].[AGAM_Inquiry] CHECK CONSTRAINT [FK_AGAM_Inquiry_AGAM_Course]
GO
ALTER TABLE [dbo].[AGAM_Inquiry] WITH CHECK ADD CONSTRAINT [FK_AGAM_Inquiry_AGAM_Users] FOREIGN KEY([UserID])
REFERENCES [dbo].[AGAM_Users] ([UserID])
GO
ALTER TABLE [dbo].[AGAM_Inquiry] CHECK CONSTRAINT [FK_AGAM_Inquiry_AGAM_Users]
GO
Can you try with changing the view to this?
SELECT TOP (100) PERCENT
AP.ID,
AP.FirstName,
AP.LastName,
AP.Branch,
AP.EnquiryID,
AC.Name,
AI.College,
AI.Mobile,
AP.ExamID,
AP.EntranceID,
AP.RegNo,
AP.VenueID,
AP.Exam,
AI.Gender,
AP.BranchID,
AP.CourseID,
AP.CreatedDate,
AI.Status,
AP.Entrance,
AP.Venue
FROM dbo.AGAM_AceOFPace AS AP
INNER JOIN dbo.AGAM_Inquiry AS AI ON AI.ID = AP.EnquiryID
INNER JOIN dbo.AGAM_Course as AC on AC.ID = AP.CourseId
ORDER BY AP.EnquiryID
Do you have an index on EnquiryId and CourseID?
Seeing as you are joining, ordering and partitioning by it you really should.
CREATE INDEX IDX_AGAM_AceOFPace_EnquiryID
ON AGAM_AceOFPace (EnquiryID)
CREATE INDEX IDX_AGAM_AceOFPace_CourseID
ON AGAM_AceOFPace (CourseID)