I have a SQL Server 2008 machine that is running backed by a SAN (not entirely certain of the SAN configuration). I've been noticing that some queries are slow to respond, so have been running some tests trying to optimize/index the slow parts. I am not a SQL Server DBA (background is more MySQL centric), but have the task of improving this performance.
My tests are the following. I created 2 tables:
CREATE TABLE "Z_SIMULATION_0"
(
"ID" INT NOT NULL,
"VALUE" INT NOT NULL,
PRIMARY KEY ("ID")
);
CREATE TABLE "Z_SIMULATION_1_TABLE"
(
"ID" BIGINT NOT NULL,
"ELEMENT" BIGINT NOT NULL,
"flag" INT NULL DEFAULT NULL,
"IS_ACTIVE" BIT NOT NULL DEFAULT b'0',
PRIMARY KEY ("ID", "ELEMENT")
);
The indexes for the Z_SIMULATION_1_TABLE
as exported by SSMS are:
CREATE NONCLUSTERED INDEX [IX_Z_SIMULATION_1_IS_ACTIVE]
ON [dbo].[Z_SIMULATION_1_TABLE] ([IS_ACTIVE] 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, FILLFACTOR = 90) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_Z_SIMULATION_INDEX_ACTIVE]
ON [dbo].[Z_SIMULATION_1_TABLE] ([ID] ASC, [IS_ACTIVE] ASC)
INCLUDE ([ELEMENT], [flag])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_ZSIMULATION1_ELEMENT]
ON [dbo].[Z_SIMULATION_1_TABLE]( [ELEMENT] 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, FILLFACTOR = 90) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_ZSIMULATION1_ID]
ON [dbo].[Z_SIMULATION_1_TABLE] ([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, FILLFACTOR = 90) ON [PRIMARY]
ALTER TABLE [dbo].[Z_SIMULATION_1_TABLE]
ADD CONSTRAINT [PK_Z_SIMULATION_1_TABLE]
PRIMARY KEY NONCLUSTERED ([ID] ASC, [ELEMENT] 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, FILLFACTOR = 90) ON [PRIMARY]
I then populated the Z_SIMULATION_0
table with 600K random (non-repeating) ID/Value pairs (IDs are between 1 & 600k).
Finally, I executed this query:
INSERT INTO Z_SIMULATION_1_TABLE (ID, ELEMENT, IS_ACTIVE)
SELECT 2, value, 0
FROM Z_SIMULATION_0
WHERE ID>=1 AND ID <= 500000;
This query took 14s to complete, which I find is significantly too long. I don't see why an insert into a blank table should take this long, and more importantly, I'm not sure how to optimize things to make it any faster.
I see the Sort (for the index I presume?) is taking the bulk of the time, but not sure what to do about that.
How can I improve the performance/reduce the amount of time it takes to do the insert? I'm open to changing/modifying/deleting indexes as required or necessary.
Z_SIMULATION_1_TABLE
in your question?(id)
index which is covered by the(id, element)
. And the(is_active)
index which is probably not useful at all. Unless the distribution is heavily one-sided (for example 95% 1 and 5% 0), in which case, a partial index would be better (smaller).(is_active)
index is not useful? Do bit fields not need indexes if trying to search by bit status?select * from table where is_acive = b'0';
is going to bring half the table (or even 20%+) then a full table scan is probably more fast so the index won't be used anyway. if you have more complex conditions that use both the bit column and other columns, then a composite index might be useful, yes. I was only commenting on the(is_active)
single-column index.