Insert blocking update query on table in SQL Server - sql

I have a table "Alert_List" with two sessions are running on it.
Session 1:
insert into Alert_List values ( "required values")
Session 2:
Update A
set Active = 0
from Alert_List A
left join STG_Alert B on A.Alert_List_Id = B.Alert_List_Id
left join STG_UserID C on A.UserID = C.UserID
where B.Alert_List_Id is null and C.UserID is null
Here STG_Alert,STG_UserIDare staging tables which will have a few selected Alert_List_Id and UserID which are not required to be deactivated.
Indexes on Alert_List as below.
ALTER TABLE [dbo].[Alert_List] ADD CONSTRAINT [PK_EA_List] PRIMARY KEY CLUSTERED
(
[Alert_List_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
CREATE NONCLUSTERED INDEX [Alert_List_INDEX] ON [dbo].[Alert_List]
(
[AVE_Id] ASC,
[Request_Id] ASC,
[User_Id] ASC,
Active ASC,
[Process_Id] ASC,
[Status_Id] ASC
)
INCLUDE ( [Alert_List_Id]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
CREATE NONCLUSTERED INDEX [indexeaml] ON [dbo].[Alert_List]
(
[User_Id] ASC,
[Process_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
One query from above two failing with below error.
Transaction (Process ID 85) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
I dont want to use WITH(NOLOCK) nor ALLOW_SNAPSHOT_ISOLATION in this case.
Let me know if you have any other ways to solve this issue.

Related

Azure DB/MSSQL 2017 query performance regression

I have this pretty simple table with 17m records in it:
CREATE TABLE [dbo].[LineNumbers](
[Id] [int] IDENTITY(1,1) NOT NULL,
[LineDescriptionId] [int] NOT NULL,
[ProtocolId] [int] NULL,
[Value] [int] NULL,
CONSTRAINT [PK_LineNumbers] 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]
Query to the table with additional join works fine, if there is no ProtocolId in it:
select top 1
ln.LineDescriptionId
from LineNumbers ln
join LineDescriptions ld on ld.Id = ln.LineDescriptionId and ld.ProtocolSetId = 25
-- Elapsed time: 00:00:00.1718750
Execution plan: https://www.brentozar.com/pastetheplan/?id=rJV34gvR7
But when I try to add ProtocolId to the field list, query time grows dramatically:
select top 1
ln.ProtocolId
from LineNumbers ln
join LineDescriptions ld on ld.Id = ln.LineDescriptionId and ld.ProtocolSetId = 25
-- Elapsed time: 00:02:19.6464843
Execution plan: https://www.brentozar.com/pastetheplan/?id=SkG-hyDCQ
Also, this works smooth:
select top 1
(select ProtocolId from LineNumbers where LineNumbers.Id = ln.Id) as ProtocolId
from LineNumbers ln
join LineDescriptions ld on ld.Id = ln.LineDescriptionId and ld.ProtocolSetId = 25
-- Elapsed time: 00:00:00.1718750
Tried this queries and variations on Azure DB and local MSSQL 2017. Results are the same. As long as I keep ProtocolId out of the field list everything is fine.
Is there some mistake in my data scheme (everything was created via migrations of Entity Framework)?
CREATE TABLE [dbo].[LineNumbers](
[Id] [int] IDENTITY(1,1) NOT NULL,
[LineDescriptionId] [int] NOT NULL,
[ProtocolId] [int] NULL,
[Value] [int] NULL,
CONSTRAINT [PK_LineNumbers] 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
/****** Object: Index [IX_LineNumbers_LineDescriptionId] Script Date: 21.11.2018 10:47:09 ******/
CREATE NONCLUSTERED INDEX [IX_LineNumbers_LineDescriptionId] ON [dbo].[LineNumbers]
(
[LineDescriptionId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object: Index [IX_LineNumbers_LineDescriptionId_Value] Script Date: 21.11.2018 10:47:09 ******/
CREATE NONCLUSTERED INDEX [IX_LineNumbers_LineDescriptionId_Value] ON [dbo].[LineNumbers]
(
[LineDescriptionId] ASC,
[Value] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object: Index [IX_LineNumbers_ProtocolId] Script Date: 21.11.2018 10:47:09 ******/
CREATE NONCLUSTERED INDEX [IX_LineNumbers_ProtocolId] ON [dbo].[LineNumbers]
(
[ProtocolId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[LineNumbers] WITH NOCHECK ADD CONSTRAINT [FK_LineNumbers_LineDescriptions_LineDescriptionId] FOREIGN KEY([LineDescriptionId])
REFERENCES [dbo].[LineDescriptions] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[LineNumbers] CHECK CONSTRAINT [FK_LineNumbers_LineDescriptions_LineDescriptionId]
GO
ALTER TABLE [dbo].[LineNumbers] WITH NOCHECK ADD CONSTRAINT [FK_LineNumbers_Protocols_ProtocolId] FOREIGN KEY([ProtocolId])
REFERENCES [dbo].[Protocols] ([Id])
GO
ALTER TABLE [dbo].[LineNumbers] CHECK CONSTRAINT [FK_LineNumbers_Protocols_ProtocolId]
GO
Eventually, I solved it by adding nonclustered index on field LineNumbers.LineDescriptionId with inclusion of LineNumbers.ProtocolId
CREATE NONCLUSTERED INDEX [IX_LineNumbers_LineDescriptionId_ProtocolId] ON
[dbo].[LineNumbers]([LineDescriptionId] ASC)
INCLUDE ([ProtocolId])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
Result:
SELECT TOP 1
ln.ProtocolId
FROM LineNumbers ln
JOIN LineDescriptions ld ON ld.Id = ln.LineDescriptionId AND ld.ProtocolSetId = 25
-- Elapsed time: 00:00:00.1403155
Execution plan: https://www.brentozar.com/pastetheplan/?id=Syywn1wRQ
Why does it work that way?
For example, if I'd do similar use case with PostgreSQL then there is no need in any additional indexes at all (beside obvious FK indexes on ProtocolId and LineDescriptionId fields).

Updating SQL Database Table with 30M Rows

I have a MS SQL table with approx 30M rows that I need to update a field based on the previous records. Here is an update that works but it is taking an incredible amount of time:
UPDATE AccountTransaction
SET EndingBalance = (SELECT COALESCE(SUM(b.amount), 0)
FROM AccountTransaction AS b
WHERE b.AccountId = AccountTransaction.AccountId
and b.Date <= AccountTransaction.Date
and (b.Date != AccountTransaction.Date
or b.CreatedDate < AccountTransaction.CreatedDate))
+ Amount
Here is the full DDL:
CREATE TABLE [dbo].[AccountTransaction](
[AccountTransactionId] [uniqueidentifier] NOT NULL,
[AccountId] [uniqueidentifier] NOT NULL,
[Amount] [decimal](16, 2) NOT NULL,
[EndingBalance] [decimal](16, 2) NOT NULL,
[Date] [date] NOT NULL,
[CreatedDate] [datetime2](3) NOT NULL,
CONSTRAINT [PkAccountTransaction] PRIMARY KEY CLUSTERED
(
[AccountTransactionId] 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 NONCLUSTERED INDEX [IxAccountTransaction_AccountId_Date_CreatedDate] ON [dbo].[AccountTransaction]
(
[AccountId] ASC,
[Date] ASC,
[CreatedDate] ASC
)
INCLUDE ([AccountTransactionId],
[Amount],
[EndingBalance]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IxAccountTransaction_AccountId] ON [dbo].[AccountTransaction]
(
[AccountId] ASC
)
INCLUDE ([AccountTransactionId],
[Amount],
[EndingBalance],
[Date],
[CreatedDate]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
The following should yield much better performance and will be able to take advantage of the IxAccountTransaction_AccountId_Date_CreatedDate index...
WITH
cte_Runningtotal AS (
SELECT
at1.EndingBalance,
NewEB = SUM(at1.Amount) OVER (PARTITION BY at1.AccountId ORDER BY at1.[Date] ROWS UNBOUNDED PRECEDING)
FROM
dbo.AccountTransaction at1
)
UPDATE rt SET
rt.EndingBalance = rt.NewEB
FROM
cte_Runningtotal rt;

SQL Server slow select from large Table

i have 2 Really Big sql server Database tables for IOT Project
First TABLE IS Message (rows count 7,423,889,085 rows)
CREATE TABLE [aymax].[Message](
[MessageId] [bigint] IDENTITY(1,1) NOT NULL,
[ObjectId] [int] NOT NULL,
[TimeStamp] [datetime] NOT NULL CONSTRAINT [DF__Message__TimeSta__3B75D760] DEFAULT (getdate()),
[GpsTime] [datetime] NOT NULL,
[VisibleSatelites] [int] NOT NULL,
[X] [float] NOT NULL,
[Y] [float] NOT NULL,
CONSTRAINT [Message_PK] PRIMARY KEY NONCLUSTERED
(
[MessageId] 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
Second table is MessageSensors , row count (26,359,568,037 rows) , this table have value for each sensor in message table
CREATE TABLE [aymax].[MessageSensors](
[MessageId] [bigint] NOT NULL,
[DataSourceId] [int] NOT NULL,
[Value] [float] NOT NULL CONSTRAINT [DF__AnalogDat__Value__5812160E] DEFAULT ((0)),
CONSTRAINT [AnalogData_PK] PRIMARY KEY CLUSTERED
(
[MessageId] ASC,
[DataSourceId] 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
my problem that seek by time interval between 2 date time is really slow , also it became more slow if i select with message sensor data , also when i use sp_BlitzIndex check from brentozar.com it say that i have
"Indexaphobia: High value missing index"
[aymax].[MessageSensors] (EQUALITY: [DataSourceId], [Value] INCLUDES: [MessageId] )
[aymax].[MessageSensors] EQUALITY: [Value] INCLUDES: [MessageId], [DataSourceId]
I belive that create this 2 index is will increase storage alot , also will take too much time to be created , i need your advice for both table regarding index
my current indexes
1-
CREATE NONCLUSTERED INDEX [IX_gpstime_objectid] ON [aymax].[Message]
(
[GpsTime] ASC
)
INCLUDE ( [MessageId],
[ObjectId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
2-
alter TABLE [aymax].[Message] ADD CONSTRAINT [Message_PK] PRIMARY KEY NONCLUSTERED
(
[MessageId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
3rd-
ALTER TABLE [aymax].[MessageSensors] ADD CONSTRAINT [AnalogData_PK] PRIMARY KEY CLUSTERED
(
[MessageId] ASC,
[DataSourceId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
4-
CREATE NONCLUSTERED INDEX [MessageData_DataSourceId_IDX] ON [aymax].[MessageSensors]
(
[DataSourceId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
any help please , i need to make a fast retrieve from message , and message sensor
update
while doing some investigate i found that select float value will slow up the result too much , from 1 second to 3 minutes
SELECT m.messageid,
m.objectid,
m.gpstime,
m.x,
m.y,
-- slow is here if i replace md.value with md.messageId will return fast , md.value is float
md.Value ,
0
FROM aymax.[message] m WITH (nolock)
left JOIN aymax.MessageSensors md WITH (nolock)
ON m.messageid = md.messageid
AND md.datasourceid = 425732
WHERE m.objectid = 14099
AND m.gpstime BETWEEN '2017-04-01 19:46:18.607' AND '2017-04-10 19:05:18.607'
Possible solutions:
Filtered index (filter by date and do not index old data)
https://learn.microsoft.com/en-us/sql/relational-databases/indexes/create-filtered-indexes.
Clustered index on GpsTime, MessageId (Espessially if you have no plans about another indexes). Requires rebuild your table.
Partitions (see #Siyaul's comments)

Why is index scan used instead of index seek?

I created unique, clustered indices on two large tables that I have to join, but those indices are not used as evidenced by the query plan. When I force the use of those indices with a hint, an index scan is used and performance gets much worse. The unique key of one table is the foreign key of the second table, so this puzzles me. Here is the schema. The two tables are LOC and POL. LOC has 7 million odd rows, and POL has over 6 million rows.
CREATE TABLE [dbo].[LOC](
[acct_num] [char](30) NOT NULL,
[cntr_num] [char](30) NOT NULL,
[lob_cde] [char](2) NOT NULL,
[ste_locn_nme] [char](30) NOT NULL,
[buldg_num] [char](20) NOT NULL,
[prctr_cde] [char](3) NULL,
...more fields...
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IDX_All] ON [dbo].[LOC]
(
[acct_num] ASC,
[cntr_num] ASC,
[lob_cde] ASC,
[buldg_num] ASC,
[prctr_cde] ASC,
[spcl_cond_1_id] ASC,
[spcl_cond_2_id] ASC,
[spcl_cond_3_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE UNIQUE CLUSTERED INDEX [IDX_LOC_PKEY] ON [dbo].[LOC]
(
[acct_num] ASC,
[lob_cde] ASC,
[prctr_cde] ASC,
[cntr_num] ASC,
[ste_locn_nme] ASC,
[buldg_num] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
... more non-unique indices on LOC, each on single columns: buldg_num, prctr_cde, acct_num
CREATE TABLE [dbo].[POL](
[acct_num] [char](30) NOT NULL,
[cntr_num] [char](30) NOT NULL,
[lob_cde] [char](2) NOT NULL,
[prctr_cde] [char](3) NULL,
...more fields...
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IDX_All] ON [dbo].[POL]
(
[acct_num] ASC,
[cntr_num] ASC,
[lob_cde] ASC,
[prctr_cde] ASC,
[acct_nme] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE UNIQUE CLUSTERED INDEX [IDX_POL_PKEY] ON [dbo].[POL]
(
[acct_num] ASC,
[lob_cde] ASC,
[prctr_cde] ASC,
[cntr_num] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
... more non-unique indices on POL, each on single columns: cntr_num, prctr_cde
As you can see, the four fields of the POL table's unique key (acct_num, lob_cde, prctr_cde, cntr_num) are the first four columns of the LOC table's primary key. Here is one query I want to run, like many that will join these two tables:
select
[Easy matches] = COUNT(*)
FROM LOC INNER JOIN POL ON (
LOC.acct_num = POL.acct_num
AND LOC.lob_cde = POL.lob_cde
AND LOC.prctr_cde = POL.prctr_cde
AND LOC.cntr_num = POL.cntr_num)
Without hints, this likes to use the IDX_prctr_cde index from each table. The prctr_cde column is not very selective; there are only seven different values in the LOC or POL tables. If I hint that the query should use IDX_cntr_num index, I get good performance, since it is a highly selective column (over 6 million distinct values in each table). acct_num is almost as selective as cntr_num, also with over 6 million distinct values.
Why is a non-selective index used by default? Why is switching to using the unique, clustered index making the query run much slower? (10x, 20x or even 30x slower.)
Note: The hint I used was:
OPTION (
TABLE HINT(POL, INDEX (IDX_POL_PKEY)),
TABLE HINT(LOC, INDEX (IDX_LOC_PKEY))
)
Note: I am using SQL Server 2005 and SQL Server 2008.

How long should an select into query take when selecting from a table with ~200 million rows in sql server 2005?

I have a table with 193,569,270 rows in a SQL Server 2005 database. The table houses activities that are performed by users of our website. The table is defined as:
Name DataType
ID int (identity) PK
ActivityTime datetime
PersonID int (should be an FK, but isn't)
ActivityTypeID int (should be an FK, but isn't)
Data1 varchar(50)
Data2 varchar(50)
I have the following indexes:
CREATE NONCLUSTERED INDEX [_MS_Sys_3] ON [dbo].[tblPersonActivity] ([PersonID] ASC)
INCLUDE ( [ID], [ActivityTime], [ActivityTypeID], [Data1], [Data2])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_Activity] ON [dbo].[tblPersonActivity] ([PersonID] ASC, [ActivityTypeID] ASC, ActivityTime] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_tblPersonActivity_PersonArchive] ON [dbo].[tblPersonActivity] ([ActivityTime] ASC)
INCLUDE ([ID], [PersonID], [ActivityTypeID], [Data1], [Data2])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblPersonActivity] ADD CONSTRAINT [PK_tblPersonActivity] PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
This is the query I've written:
declare #archiveDate datetime
declare #curDate datetime
declare #startDate datetime
declare #curYear int
declare #preYear int
set #curDate = getdate()
set #curYear = year(#curDate)
set #preYear = #curYear - 1
set #archiveDate = #curDate
set #startDate = cast(('1/1/' + cast(#preYear as varchar(4))) as datetime)
declare #InactivePersons table
(PersonID int not null PRIMARY KEY)
insert into #InactiveBuyers
select
b.PersonID
from
HBM.dbo.tblPersons b with (INDEX(IX_tblPersons_InactiveDate_PersonID), nolock)
where
b.InactiveDate is not null
and b.InactiveDate '1/1/1900'
and b.InactiveDate '12/31/1899'
and b.InactiveDate = #StartDate
The last time I ran the query it ran for over 1 day before I killed it. Have I missed something or is this just going to take that kind of time?
Thanks for any help you can provide.
Wayne E. Pfeffer
No this should not take that long if your database is properly set up and indexed.
First you need to create those FKs! There is not excuse for not having them to ensure your data integrity. FKs should have their own indexes.
Inactive date deosn't seem to be in your table structure. Is it a date field? Make it one if it is not or you are wasting time doing implicit conversions.
b.InactiveDate is not null
and b.InactiveDate '1/1/1900'
and b.InactiveDate '12/31/1899'
and b.InactiveDate = #StartDate
This whole where clause doesn't make sense. If you are looking for the records that match #startdate then you don't need any of the rest.
Check out the Execution plan to see where this is taking so long, something is causing a table scan.
And if there will be large numbers of records in the table varaible, then a temp table tends to perform faster. You don't say what you are doing with this table in the rest of the proc, are you sure it is the insert statement taking the most time or something else you are doing?