Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Administration
 heap table

Author  Topic 

arkiboys
Master Smack Fu Yak Hacker

1433 Posts

Posted - 2012-06-13 : 07:42:11
Hi,
I know if there is no clustered index in the table i.e. heap table, then the system automatically builds a PK.
Is there a link you can refer me to for further reading on this very topic where the system creates a PK when the table is a heap?

Thanks

robvolk
Most Valuable Yak

15732 Posts

Posted - 2012-06-13 : 07:53:08
quote:
I know if there is no clustered index in the table i.e. heap table, then the system automatically builds a PK.
False. A primary key is a logical construct. Heaps are physical. You're probably confusing primary key with clustered index, they are not the same thing. Heaps maintain a unique row identifier (RID) but they are not a primary key. Primary keys are never automatically created.
quote:
Is there a link you can refer me to for further reading on this very topic where the system creates a PK when the table is a heap?
Read up on heaps here: http://goo.gl/Cz9Ky
Go to Top of Page

Sachin.Nand

2937 Posts

Posted - 2012-06-13 : 08:07:10
quote:
Originally posted by robvolk

...Heaps maintain a unique row identifier (RID) but they are not a primary key...



I think that is not true.A heap will never maintain a unique identifier until a primary or unique key is defined on it.

After Monday and Tuesday even the calendar says W T F ....
Go to Top of Page

arkiboys
Master Smack Fu Yak Hacker

1433 Posts

Posted - 2012-06-13 : 08:09:46
quote:
Originally posted by robvolk

quote:
I know if there is no clustered index in the table i.e. heap table, then the system automatically builds a PK.
False. A primary key is a logical construct. Heaps are physical. You're probably confusing primary key with clustered index, they are not the same thing. Heaps maintain a unique row identifier (RID) but they are not a primary key. Primary keys are never automatically created.
quote:
Is there a link you can refer me to for further reading on this very topic where the system creates a PK when the table is a heap?
Read up on heaps here: http://goo.gl/Cz9Ky


Hi, can you please refer me to a link which show the RID is created if the table is a heap?
Thanks
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2012-06-13 : 09:34:05
quote:
Originally posted by Sachin.Nand

quote:
Originally posted by robvolk

...Heaps maintain a unique row identifier (RID) but they are not a primary key...



I think that is not true.A heap will never maintain a unique identifier until a primary or unique key is defined on it.

After Monday and Tuesday even the calendar says W T F ....



NAh -- they do. Otherwise how would the engine be able to identify rows?

When you do a seek on an index on a heap you see RID lookups in the execution plan. Even without a unique or primary key.
Consider:


IF OBJECT_ID('tempdb..#foo') IS NOT NULL DROP TABLE #foo
CREATE TABLE #foo (
[key] INT
, [value] VARCHAR(255)
)

CREATE INDEX keys ON #foo ([key])

INSERT #foo
SELECT CAST(CAST(NEWID() AS VARBINARY(255)) AS INT)
, CAST(CAST(NEWID() AS VARBINARY(255)) AS VARCHAR(255))
FROM
sys.objects AS a
CROSS JOIN sys.objects AS b

INSERT #foo VALUES (10, 'HI THERE')

SELECT * FROM #foo WHERE [key] = 10


The last statement generates this plan
[code]
|--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000]))
|--Index Seek(OBJECT:([tempdb].[dbo].[#foo]), SEEK:([tempdb].[dbo].[#foo].[key]=(10)) ORDERED FORWARD)
|--RID Lookup(OBJECT:([tempdb].[dbo].[#foo]), SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)


Transact Charlie

Msg 3903.. The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2012-06-13 : 09:42:49
quote:
Hi, can you please refer me to a link which show the RID is created if the table is a heap?
How about reading the link I provided and clicking on the other links inside it? And Google works for everyone, not just me.
quote:
I think that is not true.A heap will never maintain a unique identifier until a primary or unique key is defined on it.
The RID has to be unique, it consists of file ID, page ID and slot number. You can't store two rows in the exact same location. Moreover you can't create a unique index on the RID because it's not accessible (not in a documented way anyhow, and I just tried it anyway and failed). Here's an example:
create table #a(a int null)
insert #a default values
insert #a default values
insert #a default values
insert #a default values

select *,sys.fn_PhysLocFormatter(%%physloc%%) from #a
That's another reason why RID is not a primary key, a primary key cannot be applied to a nullable column. RID is not a column and, technically, not a value either.

More info on heaps at Paul Randal's blog: http://goo.gl/eJwBb

There's more than that, but that's the only one I could find quickly. Read Paul.

Go to Top of Page

nigelrivett
Master Smack Fu Yak Hacker

3385 Posts

Posted - 2012-06-13 : 09:47:27
If the server has a clustered index then the rid is the clustered index columns plus a sequence number if the index is not unique.
If there is no clustered index then it is generated.

The rid is included in the leaf level of every non-clustered index - which is why a wide clustered index can be bad for performance and disk space but give more covering indexes than you might expect.

==========================================
Cursors are useful if you don't know sql.
SSIS can be used in a similar way.
Beer is not cold and it isn't fizzy.
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2012-06-13 : 10:16:25
quote:
If the server has a clustered index then the rid is the clustered index columns
Technically that's not correct either. RIDs do not reference the clustering key at all.
quote:
plus a sequence number if the index is not unique.
Ummm, the INDEX is unique, I think you mean the key columns, by themselves, are not unique. The unique-ifier is a 4 byte integer that is padded to the clustering key to make it unique.

I apologize for being pedantic, it happens after you hear Paul describe it and complain about the misconceptions around it.
Go to Top of Page

Sachin.Nand

2937 Posts

Posted - 2012-06-13 : 15:31:09
quote:
Originally posted by robvolk

quote:
Hi, can you please refer me to a link which show the RID is created if the table is a heap?
How about reading the link I provided and clicking on the other links inside it? And Google works for everyone, not just me.
quote:
I think that is not true.A heap will never maintain a unique identifier until a primary or unique key is defined on it.
The RID has to be unique, it consists of file ID, page ID and slot number. You can't store two rows in the exact same location. Moreover you can't create a unique index on the RID because it's not accessible (not in a documented way anyhow, and I just tried it anyway and failed). Here's an example:
create table #a(a int null)
insert #a default values
insert #a default values
insert #a default values
insert #a default values

select *,sys.fn_PhysLocFormatter(%%physloc%%) from #a
That's another reason why RID is not a primary key, a primary key cannot be applied to a nullable column. RID is not a column and, technically, not a value either.

More info on heaps at Paul Randal's blog: http://goo.gl/eJwBb

There's more than that, but that's the only one I could find quickly. Read Paul.





Again I would say RID key does not have to be unique in a heap table.

Also what you are pointing out is the physical location of the data returned by sys.fn_PhysLocFormatter(%%physloc%%). Optimizer does not use that value to identify rows from heaps.

After Monday and Tuesday even the calendar says W T F ....
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2012-06-13 : 16:11:24
quote:
Again I would say RID key does not have to be unique in a heap table.
Alright, please post an example where 1 RID points to 2 or more rows. RID is not a key either.
quote:
Also what you are pointing out is the physical location of the data returned by sys.fn_PhysLocFormatter(%%physloc%%). Optimizer does not use that value to identify rows from heaps.
I know that too. A RID isn't recorded anywhere except in the leaf level of a non-clustered index on a heap table. The optimizer doesn't care whether the non-clustered index is based on a heap or a B-tree structure.
Go to Top of Page

Sachin.Nand

2937 Posts

Posted - 2012-06-13 : 16:43:32
quote:
Originally posted by robvolk

quote:
Again I would say RID key does not have to be unique in a heap table.
Alright, please post an example where 1 RID points to 2 or more rows. RID is not a key either.
quote:
Also what you are pointing out is the physical location of the data returned by sys.fn_PhysLocFormatter(%%physloc%%). Optimizer does not use that value to identify rows from heaps.
I know that too. A RID isn't recorded anywhere except in the leaf level of a non-clustered index on a heap table. The optimizer doesn't care whether the non-clustered index is based on a heap or a B-tree structure.



See the following.

I have created a table with NC indexes on two different columns.

use tempdb
go
create table a(number1 int,number2 int)
create nonclustered index ix_id1 on a(number1)
go
create nonclustered index ix_id on a(number2)
go
insert a values(2,10),(3,100),(4,1000)

I am using the DBCC IND command to get the details on the pages used by indexes.
DBCC TRACEON(3604)

DBCC IND(tempdb,a,-1)

In my case I am getting the pagepid 4840 and 4845 as the page ids of index pages.
Now I would use DBCC PAGE command to get the details of the indexes stored in these two pages

DBCC PAGE (tempdb, 1, 4840, 3)
GO
DBCC PAGE (tempdb, 1, 4845, 3)

Now if you carefully see the heap RID returned by these command you will see that they are exactly the same.

So in short this proves that RID keys does not have to be unique across heaps..


Now let us break down the RID value to get the file:page:rowid returned by fn_PhysLocFormatter.In my case one of the value returned by DBCC PAGE is 0xA312000001000000
I have used this function to convert it

declare @rowid BINARY(8)
set @rowid = 0xA312000001000000
select

CONVERT (VARCHAR(5),
CONVERT(INT, SUBSTRING(@rowid, 6, 1)
+ SUBSTRING(@rowid, 5, 1)))
+ ':'

+ CONVERT(VARCHAR(10),
CONVERT(INT, SUBSTRING(@rowid, 4, 1)
+ SUBSTRING(@rowid, 3, 1)
+ SUBSTRING(@rowid, 2, 1)
+ SUBSTRING(@rowid, 1, 1)))
+ ':'

+ CONVERT(VARCHAR(5),
CONVERT(INT, SUBSTRING(@rowid, 8, 1)
+ SUBSTRING(@rowid, 7, 1)))

So if you see the value returned by the above function it is exactly the same what is returned by fn_PhysLocFormatter(%%physloc%%).
So in short an RID key can point to the same location which does not have to be necessarily unique.

I am off to bed now...its midnight here in India.

After Monday and Tuesday even the calendar says W T F ....
Go to Top of Page

Alexander Suprun
Starting Member

4 Posts

Posted - 2012-06-18 : 16:05:52
quote:
Originally posted by Sachin.Nand
Also what you are pointing out is the physical location of the data returned by sys.fn_PhysLocFormatter(%%physloc%%). Optimizer does not use that value to identify rows from heaps.
After Monday and Tuesday even the calendar says W T F ....

I don't know why are referring to Optimizer but I'll assume that you mean SQL Server Query Processor. So it definitely uses RID, then it converts it to "file:page:slot" using fn_PhysLocFormatter (or something similar) and then uses this value to identify and extract rows from heap. That's the only way how it can be done!
Go to Top of Page

Alexander Suprun
Starting Member

4 Posts

Posted - 2012-06-18 : 16:39:23
quote:
Originally posted by Sachin.Nand
So if you see the value returned by the above function it is exactly the same what is returned by fn_PhysLocFormatter(%%physloc%%).
So in short an RID key can point to the same location which does not have to be necessarily unique.

Are you deliberately trying to confuse everyone in this topic?
You took RIDs from 2 different non-clustered indexes! Which are just pointers in this case, certainly you can create multiple pointers that point to the same record, that's basically the whole purpose of the pointer and of course these RIDs must be the same, otherwise how they can point to the same record? But robvolk was talking about RID values in heap, and if you look at the heap only you will never find 2 RIDs with the same value, because they must be unique.
Go to Top of Page

Sachin.Nand

2937 Posts

Posted - 2012-06-19 : 04:14:47
quote:
Originally posted by Alexander Suprun

Are you deliberately trying to confuse everyone in this topic?
You took RIDs from 2 different non-clustered indexes! Which are just pointers in this case, certainly you can create multiple pointers that point to the same record, that's basically the whole purpose of the pointer and of course these RIDs must be the same, otherwise how they can point to the same record? But robvolk was talking about RID values in heap, and if you look at the heap only you will never find 2 RIDs with the same value, because they must be unique.



Did you even made an effort to understand what the discussion was all about or just jumped on your guns to bash me ??

The whole point of the discussion in the fist place was that will SQL Server create unique RID keys for a heap irrespective whether they point to same record or not ,whether the heap has multiple indexes or not which I proved with an example that it is a FALSE assumption.


Only free men can negotiate..
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2012-06-19 : 07:34:44
quote:
The whole point of the discussion in the fist place was that will SQL Server create unique RID keys for a heap irrespective whether they point to same record or not ,whether the heap has multiple indexes or not which I proved with an example that it is a FALSE assumption.
With the example you posted I couldn't replicate the output you showed. I could very well be missing something but I don't think you've proven it yet. And from a common sense perspective I cannot see how RID wouldn't be unique since it's a physical storage reference. Again, if it weren't unique you could have 2 rows in the same physical location, and that makes no sense at all.
quote:
Did you even made an effort to understand what the discussion was all about or just jumped on your guns to bash me ??
I think you're taking this too personally. Also be aware that you're contradicting information provided by the person who wrote the storage engine while he worked at Microsoft. In the words of Carl Sagan, "extraordinary claims require extraordinary evidence". Sorry if it sounds like we're bashing you, but if you're right you need to go the extra mile to prove it. And it's a cheap shot to simply accuse us of not understanding.
Go to Top of Page

Alexander Suprun
Starting Member

4 Posts

Posted - 2012-06-19 : 20:00:54
quote:
Originally posted by Sachin.Nand

The whole point of the discussion in the fist place was that will SQL Server create unique RID keys for a heap
Which is true. For each record in a heap table there is only one RID and for one RID there is only one record in a table.
quote:
Originally posted by Sachin.Nandwhether the heap has multiple indexes or not which I proved with an example that it is a FALSE assumption.
Using your logic I can easily prove that Primary Key is not unique. Create a table with clustered index and then two non-clustered indexes. Then look at the pages of these 2 indexes and you will find 2 IDs with the same values. OMG! Primary Key is not unique. I found the biggest bug in SQL Server. But I doubt that anyone will believe in this. You are simply making conclusions based on misinterpretation.
Go to Top of Page

Sachin.Nand

2937 Posts

Posted - 2012-06-20 : 01:41:02
quote:
Which is true. For each record in a heap table there is only one RID and for one RID there is only one record in a table.


I know that but what I am saying is that the RID KEY (MAKE AN EFFORT TO FOCUS YOUR EYES ON THE WORD KEY) does not have to be unique.

Without making any effort of whatsoever of running my example maybe because of your INABILITY to do so you are getting over my head.If guys like you are on the forum I am better off this forum.

@Robovolk

As you quoted some saying for me.I would also like to quote something for you..

"Wise men learn more from fools than fools from the wise"...Marcus Porcius Cato

Only free men can negotiate..
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2012-06-20 : 06:28:03
quote:
Originally posted by Sachin.Nand
"Wise men learn more from fools than fools from the wise"...Marcus Porcius Cato
Can't tell which one you take me for, and it seems everyone in this thread is not learning from the other, therefore I think it's best to close it and move on before it gets acrimonious.
Go to Top of Page
   

- Advertisement -