SQL Server Rebulid Index is not completely? - sql-server

I just have a question about rebuild index.
After I had rebuilt the index, I found the physical order of pages is not completely "in order", I saw the pages which has small PID's is after the page has big PID's, as below, the page 7234 is after 23596, this is why. Why is the PID after building the index not in order from small to big or from big to small?
objectID PagePID PrePagePID NextPagePID
93243387 23590 0 0 10 NULL
93243387 7440 23583 0 2 1
93243387 7441 0 0 2 2
93243387 23583 0 7440 2 1
93243387 23589 0 23591 1 0
93243387 23591 23589 23592 1 0
93243387 23592 23591 23593 1 0
93243387 23593 23592 23594 1 0
93243387 23594 23593 23595 1 0
93243387 23595 23594 23596 1 0
93243387 23596 23595 7432 1 0
93243387 7432 23596 7433 1 0 <---------
93243387 7433 7432 7434 1 0
93243387 7434 7433 7435 1 0
93243387 7435 7434 7436 1 0

Try to run the following command just replace 'MyTable' with your tablename and verify if index is indeed fragmented.
SELECT DB_NAME(database_id) AS [Database Name]
,OBJECT_NAME(ps.OBJECT_ID) AS [Object Name]
,i.name AS [Index Name]
,ps.index_id
,ps.index_type_desc
,ps.avg_fragmentation_in_percent
,ps.fragment_count
,ps.page_count
,i.fill_factor
,i.has_filter
,i.filter_definition
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ps
INNER JOIN sys.indexes AS i WITH ( NOLOCK )
ON ps.[object_id] = i.[object_id]
AND ps.index_id = i.index_id
WHERE database_id = DB_ID()
AND OBJECT_NAME(ps.OBJECT_ID) = 'MyTable'
ORDER BY avg_fragmentation_in_percent DESC
OPTION ( RECOMPILE );
after than reogranize all indexes on that table and after rebuild it.
Organize syntax
-- Reorganize all indexes on the HumanResources.Employee table.
ALTER INDEX ALL ON HumanResources.Employee
REORGANIZE ;
GO
Rebuild syntax:
ALTER INDEX PK_Employee_BusinessEntityID ON HumanResources.Employee
REBUILD;
GO
after all that rerun the first query.

Related

How to check values of different rows of a table

I have below sample input table. In real it has lots of records.
Input:
ID
Classification
123
1
123
2
123
3
123
4
657
1
657
3
657
4
For a 'ID', I want it's records should have 'Classification' column contains all the values 1, 2, 3 and 4. If any of these values are not present then that ID's records should be considered as an exception. The output should be as below.
ID
Classification
Flag
123
1
0
123
2
0
123
3
0
123
4
0
657
1
1
657
3
1
657
4
1
Can someone please help me with how can this can be achieved in sql server.
Thanks.
There are a couple of options here, which is more performant is up to you to test, not me (especially when I don't know what indexes you have). One uses conditional aggregation, to check that all the values are there, and the other uses a subquery and counts the DISTINCT values (as I don't know if there could be duplicate classifications):
SELECT *
INTO dbo.YourTable
FROM (VALUES(123,1),
(123,2),
(123,3),
(123,4),
(657,1),
(657,3),
(657,4))V(ID,Classification);
GO
CREATE CLUSTERED INDEX CI_YourIndex ON dbo.YourTable (ID,Classification);
GO
SELECT ID,
Classification,
CASE WHEN COUNT(CASE YT.Classification WHEN 1 THEN 1 END) OVER (PARTITION BY ID) > 0
AND COUNT(CASE YT.Classification WHEN 2 THEN 1 END) OVER (PARTITION BY ID) > 0
AND COUNT(CASE YT.Classification WHEN 3 THEN 1 END) OVER (PARTITION BY ID) > 0
AND COUNT(CASE YT.Classification WHEN 4 THEN 1 END) OVER (PARTITION BY ID) > 0 THEN 1 ELSE 0
END AS Flag
FROM dbo.YourTable YT;
GO
SELECT ID,
Classification,
CASE (SELECT COUNT(DISTINCT sq.Classification)
FROM dbo.YourTable sq
WHERE sq.ID = YT.ID
AND sq.Classification IN (1,2,3,4)) WHEN 4 THEN 1 ELSE 0
END AS Flag
FROM dbo.YourTable YT;
GO
DROP TABLE dbo.YourTable;

Getting database name from table name in SQL Server

I need to get database name from table names in SQL Server. I can query 'tablenames' in the database, but how do I get the database name for each table as well?
select *
from sys.tables;
Output:
name object_id principal_id schema_id parent_object_id type type_desc create_date modify_date is_ms_shipped is_published is_schema_published lob_data_space_id filestream_data_space_id max_column_id_used lock_on_bulk_load uses_ansi_nulls is_replicated has_replication_filter is_merge_published is_sync_tran_subscribed has_unchecked_assembly_data text_in_row_limit large_value_types_out_of_row is_tracked_by_cdc lock_escalation lock_escalation_desc is_filetable is_memory_optimized durability durability_desc temporal_type temporal_type_desc history_table_id is_remote_data_archive_enabled is_external
DL_CONLog 719055 NULL 1 0 U USER_TABLE 43:24.3 01:41.0 0 0 0 0 NULL 10 0 1 0 0 0 0 0 0 0 0 0 TABLE 0 0 0 SCHEMA_AND_DATA 0 NON_TEMPORAL_TABLE NULL 0 0
DL_TIMJobImportLinkBrokerToModule 771110 NULL 1 0 U USER_TABLE 45:12.1 45:20.7 0 0 0 1 NULL 64 0 1 0 0 0 0 0 0 0 0 0 TABLE 0 0 0 SCHEMA_AND_DATA 0 NON_TEMPORAL_TABLE NULL 0 0
Try using
SELECT * FROM INFORMATION_SCHEMA.TABLES
sys.tables gives you list of table of current database. The current database name can be query from db_name().
If you are looking for a list of tables of a specific database, use db1.sys.tables
Not really sure what is your requirement, but if you want current database & table name, you can query INFORMATION_SCHEMA.TABLES

Calculate Type of the member in a table (Self Join/Case When or any other possible way)

Here is the Table :
If OBJECT_ID ('tempdb..##SelfCount') Is not null
drop table #SelfCount
create table #SelfCount (CanID int , CanType int)
insert into #SelfCount (CanID, CanType)
values
(1,0),
(2,0),
(1,1),
(2,1),
(1,2),
(1,2),
(1,0)
CanID CanType
1 0
2 0
1 1
2 1
1 2
1 2
1 0
I'm Expecting the result to be like this
CanID Self Spouse Dependent
1 2 1 2
2 1 1 0/NULL --It doesn't matter if it's nUll or 0
I wrote this query
select CanID,
case
When CanType = 0 then count(CanType)
end as [self],
case
when CanType = 1 then count(CanType)
end as [Spouse],
Case
When CanType = 2 then count(CanType)
end as [Dependent]
from #SelfCount
Group by CanID, CanType
But the Result Set is like this :
CanID Self Spouse Dependent
1 2 NULL NULL
2 1 NULL NULL
1 NULL 1 NULL
2 NULL 1 NULL
1 NULL NULL 2
I've tried the Recursive method, If anyone could provide both Recursive as well as Set processing method, it'll be greatly appreciated.
By including the CanType in the group by clause, you're getting a separate result row per distinct value of CanType (and CanId, since it's also contained in the group by clause).
Instead, you should only have CanId in the group by clause, and apply different counts on case expressions:
SELECT CanID,
COUNT (CASE CanType WHEN 0 THEN 1 END) AS [Self],
COUNT (CASE CanType WHEN 1 THEN 1 END) AS [Spouse],
COUNT (CASE CanType WHEN 2 THEN 1 END) AS [Dependent],
FROM #SelfCount
GROUP BY CanID
May be this is what you need:
select CanID,
sum(case when CanType = 0 then 1 else 0 end) as [Self],
sum(case when CanType = 1 then 1 else 0 end) as [Spouse],
sum(case when CanType = 2 then 1 else 0 end) as [Dependent]
from #SelfCount
group by CanID
You can try with PIVOT:
select
CanID,
[0] as Self,
[1] as Spouse,
[2] as Dependent
from tab
pivot
(
count (CanType)
for CanType IN ([0], [1], [2])
) as pvt
Basically, it will group by all columns not declared inside the PIVOT clause (actually, just the CanID) and then create three aggregation COUNT columns, one FOR each CanType IN the list of values. If you need to count more values, just define them in the IN clause and in the SELECT clause.

Optimize time critical t-sql statement

I have a stored procedure and it is very slow, and i am not sure what i can improve.
The sql server table EntityValue only contains 1'800 rows.
here is the stored procedure:
CREATE PROCEDURE [dbo].[GetReportLabelValues](
#UnitIds UniqueIdentifierTableType readonly,
#LabelIds UniqueIdentifierTableType readonly)
AS
BEGIN
SELECT LabelValue.EntityId AS [LabelId], LabelValue.UnitId AS [UnitId], LabelValue.Value AS [Value]
FROM EntityValue, LabelValue
WHERE
EntityValue.IsDeleted = 0 AND
EntityValue.UnitId = LabelValue.UnitId AND
EntityValue.EntityId = LabelValue.EntityId AND
EXISTS (SELECT 1 FROM #UnitIds WHERE EntityValue.UnitId = [#UnitIds].Id) AND
EXISTS (SELECT 1 FROM #LabelIds WHERE EntityValue.EntityId = [#LabelIds].Id)
END;
What is wrong with this statement? Or do i need to set some additional indices?
Thank you for your help in advance :)
best
laurin
Edit:
Here is the excution plan:
DECLARE #unitIds AS UniqueIdentifierTableType;
INSERT INTO #unitIds ([Id]) VALUES ('63ABF15E-B8B0-4240-9B90-08F324D5179E') 1 1 0 NULL NULL 1 NULL 1 NULL NULL NULL 0.01000216 NULL NULL INSERT 0 NULL
|--Table Insert(OBJECT:(#unitIds), SET:([Id] = [Expr1004]), DEFINE:([Expr1004]={guid'63ABF15E-B8B0-4240-9B90-08F324D5179E'})) 1 2 1 Table Insert Insert OBJECT:(#unitIds), SET:([Id] = [Expr1004]), DEFINE:([Expr1004]={guid'63ABF15E-B8B0-4240-9B90-08F324D5179E'}) [Expr1004]={guid'63ABF15E-B8B0-4240-9B90-08F324D5179E'} 1 0.01 1E-06 9 0.01000216 NULL NULL PLAN_ROW 0 1
DECLARE #labelIds AS UniqueIdentifierTableType;
INSERT INTO #labelIds ([Id]) VALUES ('4E75B50C-E647-42E7-A87F-2D23D8B63D17') 2 3 0 NULL NULL 2 NULL 1 NULL NULL NULL 0.01000216 NULL NULL INSERT 0 NULL
|--Table Insert(OBJECT:(#labelIds), SET:([Id] = [Expr1004]), DEFINE:([Expr1004]={guid'4E75B50C-E647-42E7-A87F-2D23D8B63D17'})) 2 4 3 Table Insert Insert OBJECT:(#labelIds), SET:([Id] = [Expr1004]), DEFINE:([Expr1004]={guid'4E75B50C-E647-42E7-A87F-2D23D8B63D17'}) [Expr1004]={guid'4E75B50C-E647-42E7-A87F-2D23D8B63D17'} 1 0.01 1E-06 9 0.01000216 NULL NULL PLAN_ROW 0 1
exec dbo.GetReportLabelValues #unitIds, #labelIds 3 5 0 NULL NULL 3 NULL NULL NULL NULL NULL NULL NULL NULL EXECUTE PROC 0 NULL
CREATE PROCEDURE GetReportLabelValues(
#UnitIds UniqueIdentifierTableType readonly,
#LabelIds UniqueIdentifierTableType readonly)
AS
BEGIN
SELECT LabelValue.EntityId AS [LabelId], LabelValue.UnitId AS [UnitId], LabelValue.Value AS [Value]
FROM EntityValue, LabelValue
WHERE
EntityValue.IsDeleted = 0 AND
EntityValue.UnitId = LabelValue.UnitId AND
EntityValue.EntityId = LabelValue.EntityId AND
EXISTS (SELECT 1 FROM #UnitIds WHERE EntityValue.UnitId = [#UnitIds].Id) AND
EXISTS (SELECT 1 FROM #LabelIds WHERE EntityValue.EntityId = [#LabelIds].Id) 4 6 5 NULL NULL 5 NULL 1.062501 NULL NULL NULL 0.02785614 NULL NULL SELECT 0 NULL
|--Stream Aggregate(GROUP BY:([ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId]) DEFINE:([ABB_MDB2_Test].[dbo].[LabelValue].[Value]=ANY([ABB_MDB2_Test].[dbo].[LabelValue].[Value]))) 4 8 6 Stream Aggregate Aggregate GROUP BY:([ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId]) [ABB_MDB2_Test].[dbo].[LabelValue].[Value]=ANY([ABB_MDB2_Test].[dbo].[LabelValue].[Value]) 1.062501 0 1.062501E-06 343 0.02785614 [ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[Value] NULL PLAN_ROW 0 1
|--Nested Loops(Inner Join, OUTER REFERENCES:([ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [Id])) 4 9 8 Nested Loops Inner Join OUTER REFERENCES:([ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [Id]) NULL 1.062501 0 4.441255E-06 375 0.02785508 [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[Value] NULL PLAN_ROW 0 1
|--Nested Loops(Inner Join, WHERE:([ABB_MDB2_Test].[dbo].[EntityValue].[EntityId]=[Id])) 4 10 9 Nested Loops Inner Join WHERE:([ABB_MDB2_Test].[dbo].[EntityValue].[EntityId]=[Id]) NULL 1.062501 0 0.0001594845 55 0.02455766 [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId], [Id] NULL PLAN_ROW 0 1
| |--Nested Loops(Inner Join, OUTER REFERENCES:([Id])) 4 12 10 Nested Loops Inner Join OUTER REFERENCES:([Id]) NULL 38.15419 0 0.0001594845 39 0.01814615 [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId] NULL PLAN_ROW 0 1
| | |--Sort(DISTINCT ORDER BY:([Id] ASC)) 4 13 12 Sort Distinct Sort DISTINCT ORDER BY:([Id] ASC) NULL 1 0.01126126 0.000100023 23 0.01464438 [Id] NULL PLAN_ROW 0 1
| | | |--Table Scan(OBJECT:(#UnitIds)) 4 14 13 Table Scan Table Scan OBJECT:(#UnitIds) [Id] 1 0.003125 0.0001581 23 0.0032831 [Id] NULL PLAN_ROW 0 1
| | |--Clustered Index Seek(OBJECT:([ABB_MDB2_Test].[dbo].[EntityValue].[PK_EntityValue]), SEEK:([ABB_MDB2_Test].[dbo].[EntityValue].[UnitId]=[Id]), WHERE:([ABB_MDB2_Test].[dbo].[EntityValue].[IsDeleted]=(0)) ORDERED FORWARD) 4 15 12 Clustered Index Seek Clustered Index Seek OBJECT:([ABB_MDB2_Test].[dbo].[EntityValue].[PK_EntityValue]), SEEK:([ABB_MDB2_Test].[dbo].[EntityValue].[UnitId]=[Id]), WHERE:([ABB_MDB2_Test].[dbo].[EntityValue].[IsDeleted]=(0)) ORDERED FORWARD [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId], [ABB_MDB2_Test].[dbo].[EntityValue].[IsDeleted] 38.15419 0.003125 0.0001989696 40 0.00332397 [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId], [ABB_MDB2_Test].[dbo].[EntityValue].[IsDeleted] NULL PLAN_ROW 0 1
| |--Table Scan(OBJECT:(#LabelIds)) 4 17 10 Table Scan Table Scan OBJECT:(#LabelIds) [Id] 1 0.0032035 7.96E-05 31 0.006240574 [Id] NULL PLAN_ROW 0 38.15419
|--Clustered Index Seek(OBJECT:([ABB_MDB2_Test].[dbo].[LabelValue].[PK_LabelValue]), SEEK:([ABB_MDB2_Test].[dbo].[LabelValue].[UnitId]=[ABB_MDB2_Test].[dbo].[EntityValue].[UnitId] AND [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId]=[Id]) ORDERED FORWARD) 4 19 9 Clustered Index Seek Clustered Index Seek OBJECT:([ABB_MDB2_Test].[dbo].[LabelValue].[PK_LabelValue]), SEEK:([ABB_MDB2_Test].[dbo].[LabelValue].[UnitId]=[ABB_MDB2_Test].[dbo].[EntityValue].[UnitId] AND [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId]=[Id]) ORDERED FORWARD [ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[Value] 1 0.003125 0.0001581 343 0.003292982 [ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[Value] NULL PLAN_ROW 0 1.062501
Try this, I converted the sub-queries to joins.
CREATE PROCEDURE [dbo].[GetReportLabelValues]
(
#UnitIds UniqueIdentifierTableType readonly,
#LabelIds UniqueIdentifierTableType readonly
)
AS
BEGIN
SELECT LabelValue.EntityId AS [LabelId],
LabelValue.UnitId AS [UnitId],
LabelValue.Value AS [Value]
FROM EntityValue
JOIN LabelValue ON EntityValue.UnitId = LabelValue.UnitId AND
EntityValue.EntityId = LabelValue.EntityId
JOIN #UnitID ON EntityValue.UnitId = [#UnitIds].Id
JOIN #LabelIds ON EntityValue.EntityId = [#LabelIds].Id
WHERE EntityValue.IsDeleted = 0
END;

A group by challenge

Let's say I have this table MyTbl
Record Id_try Id Type IsOk DateOk
1 1 MYDB00125 A 0 NULL
2 1 MYDB00125 B 1 2012-07-19 20:10:05.000
3 1 MYDB00125 A 0 2012-07-25 14:10:05.000
4 2 MYDB00125 A 0 2012-07-19 22:10:05.000
5 1 MYDB00254 B 0 2012-07-19 22:10:05.000
6 1 MYDB00254 A 0 NULL
7 3 MYDB00125 A 1 2012-07-19 22:15:05.000
8 3 MYDB00125 B 1 2012-07-19 22:42:53.000
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 C 0 NULL
And I want a group by that brings me for each Id and Type my last "Id_Try Record".
SELECT Id, MAX(Id_Try), MyTbl.Type, IsOK, MAX(DateOk) from MyTbl
GROUP BY Id, MyTbl.Type, IsOK
Won't do, because It'll bring me the last Id_Try AND the last date (Date of record 3 in the example). And I don't care if its the last date or not, I need the date of the last Id_Try.
Is this only solved by a subselect? or a having clause could do?
This is the result expected:
Record Id_try Id Type IsOk DateOk
5 1 MYDB00254 B 0 2012-07-19 22:10:05.000
6 1 MYDB00254 A 0 NULL
7 3 MYDB00125 A 1 2012-07-19 22:15:05.000
8 3 MYDB00125 B 1 2012-07-19 22:42:53.000
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 B 0 NULL
I think you will need to break this into two pieces:
with maxIDTry as
(
SELECT MAX(Id_try) as maxId, ID
FROM MyTable
GROUP BY ID
)
SELECT * FROM MyTable as mt
INNER JOIN maxIDTry as max
ON mt.id_try = max.maxId AND mt.id = max.id
I think you want this:
select * FROM
(
select *, row_number() over (partition by id,type order by Id_try desc) as position from mytbl
) foo
where position = 1
order by record
http://www.sqlfiddle.com/#!3/95742/5
Your sample result set lists
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 A 0 NULL
But that doesn't make sense since you're saying the ID and the Id_try have the same value. I assume you meant for Id_try to be 2 maybe? Otherwise I think my results match up.
Hope this helps.
SELECT A.Record, A.Id_try, A.Id, A.Type, A.IsOk, A.DateOk
FROM MyTbl A INNER JOIN (
SELECT MAX(Id_Try) Id_Try, Id, B1.Type
from MyTbl B1
GROUP BY Id, B1.Type) AS B
ON A.Id_Try = B.Id_Try AND A.Id = B.Id AND A.Type = B.Type
ORDER BY A.RECORD

Resources