Есть знатоки MS SQL?

 
?? Andy-Andrei #17.02.2004 09:24
+
-
edit
 

Andy-Andrei

втянувшийся

Вопрос:
насколько может быть неэффективным в плане производительности использование UNIQUEIDENTIFIER (GUID) в качестве первичного ключа таблиц?

Во всем этот тип данных подходит для мой задачи просто превосходно, пытает лишь сомнение, что будет тормозить, да и размер хранения - 19 байт не шуточный.
Ты не смотри, что у меня вечно штраф висит... Я не буйный...  
+
-
edit
 

Mishka

модератор
★★☆

Хм, а разве не 16? Вот msdev help выдает:
code text
  1. typedef struct _GUID
  2. {
  3.     unsigned long        Data1;
  4.     unsigned short       Data2;
  5.     unsigned short       Data3;
  6.     unsigned char        Data4[8];
  7. } GUID;


А вот, что пишет сама MS (особенно в конце - про недостатки):
Using uniqueidentifier Data
The uniqueidentifier data type stores 16-byte binary values that operate as globally unique identifiers (GUIDs). A GUID is a unique binary number; no other computer in the world will generate a duplicate of that GUID value. The main use for a GUID is for assigning an identifier that must be unique in a network that has many computers at many sites.

A GUID value for a uniqueidentifier column is usually obtained:

In a Transact-SQL statement, batch, or script by calling the NEWID function.


In application code by calling an application API function or method that returns a GUID.
The Transact-SQL NEWID function and the application API functions and methods generate new uniqueidentifier values from the identification number of their network card plus a unique number from the CPU clock. Each network card has a unique identification number. The uniqueidentifier returned by NEWID is generated using the network card on the server. The uniqueidentifier returned by application API functions and methods is generated using the network card on the client.

A uniqueidentifier is not typically defined as a constant because it is difficult to ensure that the uniqueidentifier created is actually unique. There are two ways to specify a uniqueidentifier constant:

Character string format
'6F9619FF-8B86-D011-B42D-00C04FC964FF'

Binary format
0xff19966f868b11d0b42d00c04fc964ff

The uniqueidentifier data type does not automatically generate new IDs for inserted rows the way the IDENTITY property does. To get new uniqueidentifier values, a table must have a DEFAULT clause specifying the NEWID function, or INSERT statements must use the NEWID function:

CREATE TABLE MyUniqueTable
(UniqueColumn UNIQUEIDENTIFIER DEFAULT NEWID(),
Characters VARCHAR(10) )
GO
INSERT INTO MyUniqueTable(Characters) VALUES ('abc')
INSERT INTO MyUniqueTable VALUES (NEWID(), 'def')
GO

uniqueidentifier columns may contain multiple occurrences of an individual uniqueidentifier value, unless the UNIQUE or PRIMARY KEY constraints are also specified for the column. A foreign key column referencing a uniqueidentifier primary key in another table will have multiple occurrences of individual uniqueidentifier values when multiple rows reference the same primary key in the source table.

A table can have multiple uniqueidentifier columns. One uniqueidentifier column for each table may be specified with the ROWGUIDCOL property. The ROWGUIDCOL property indicates that the uniqueidentifier values in the column uniquely identify rows in the table. The property does not do anything to enforce this, however. The uniqueness must be enforced through other mechanisms, such as specifying the PRIMARY KEY constraint for the column. The ROWGUIDCOL property is primarily used by SQL Server replication.

The main advantage of the uniqueidentifier data type is that the values generated by the Transact-SQL NEWID function or the application GUID functions are guaranteed to be unique throughout the world.

The uniqueidentifier data type has several disadvantages:

The values are long and obscure. This makes them difficult for users to type correctly, and more difficult for users to remember.


The values are random and cannot accept any patterns that may make them more meaningful to users.


There is no way to determine the sequence in which uniqueidentifier values were generated. They are not suited for existing applications that depend on incrementing key values serially.


At 16 bytes, the uniqueidentifier data type is relatively large compared to other data types such as 4-byte integers. This means indexes built using uniqueidentifier keys may be relatively slower than implementing the indexes using an int key.
Consider using the IDENTITY property when global uniqueness is not necessary, or when having a serially incrementing key is desirable.


See Also

Data Types

uniqueidentifier
 

 
?? Andy-Andrei #18.02.2004 10:49
+
-
edit
 

Andy-Andrei

втянувшийся

Все это я уже читал, просто хочу посоветоваться с живыми людьми, узнать чужой опыт по этой теме.

Ну, размер базы особой роли не играет, места в принципе завались.
Более медленный ребилд индексов означает больше тормозов при вставке, но это тоже не очень страшно, т.к. база сравнительно медленно обновляемая.

Меня больше интересует время выборки, про которое MS тактично умолчали.
Особенно, когда выполняется многократно вложенный запрос, вдобавок, сконкатенированный через union на порядка 30-ти разных базах.
Вот здесь я тормозов, в принципе, боюсь.
Ты не смотри, что у меня вечно штраф висит... Я не буйный...  
+
-
edit
 

Mishka

модератор
★★☆

А ты попробуй. Сильно очень тормозить не должно - вроде хотя они и пишут, что упорядовачивания нет для GUID, но сравнение 16 байтных чисел на равно, меньше и больше делается на пару ассемблерных команд больше. Поэтому основная потеря в скорости это сколько элементов индекса влезает в буфер.
Т.е. я бы сказал - больших затыков не должно быть.
 
?? Andy-Andrei #18.02.2004 17:26
+
-
edit
 

Andy-Andrei

втянувшийся

Вот ведь затык, чтобы реально попробовать, придется нехилую часть клиентского приложения переписать. Ну да видно делать нечего, спасибо на добром слове.
Ты не смотри, что у меня вечно штраф висит... Я не буйный...  
+
-
edit
 

Mishka

модератор
★★☆

Дык, елы-палы, братишка, зачем? Набросай скажем схемку из 5 таблиц, скажем, или сколько у тебя там наиболее трудные SQL совокупляют. И создай базы 2 - с int и с GUID - маленькое приложение по заполнению обеих - сгенери записи в количестве N штук. А потом запусти SQL и померяй. Как первое приближение работает очень не плохо. Надо только N сделать достаточно правдоподобным, т.к. все глюки лезут далеко не в начале. Я думаю, что потратив полчаса на схему, еще полчаса на программку для генерации и 15 минут на SQL в аналайзере, ты получишь ответ.
 

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru