Вопрос об основах хранения PostgreSQL и SQL Server - PullRequest
3 голосов
/ 14 марта 2011

Я знаю, что SQL Server может хранить данные строки на уровне листьев в кластерном индексе.Я считаю, что PostgreSQL не делает этого.Если да, то какова его парадигма хранения?

Мой главный вопрос заключается в следующем.Рассмотрим следующий дизайн и данные (показанные в T-SQL):

CREATE TABLE dbo.Tree
    (
    [Key] int NOT NULL,
    ID int NOT NULL
    ) ON [PRIMARY]
GO
ALTER TABLE dbo.Tree ADD CONSTRAINT
    PK_Tree PRIMARY KEY CLUSTERED 
    (
    [Key],
    ID
    ) WITH (...) ON [PRIMARY]

INSERT INTO TREE ([Key], ID) VALUES (1, 1), (1, 2), (1, 3), (1, 4).

Поскольку это btree с обоими столбцами в качестве PK, я прав, говоря, что «[Key] = 1» будет толькобудет сохранен один раз, и «ID = [1, 2, 3, 4]» будут отдельными значениями в btree, в то время как не будет значений листьев для sé, поскольку нет столбцов строк, которые не являются частью PK?

Как это будет работать в PostgreSQL?

Ответы [ 4 ]

14 голосов
/ 14 марта 2011

TL; версия DR - ваши значения ключей всегда хранятся на диске, независимо от реализации СУБД.

PostgreSQL будет хранить 4 строки на странице на диске, по одной для каждой вставленной строки.SQL Server также будет хранить 4 строки на диске.B-дерево - это структура поиска, а не структура хранения на уровне страницы.

На базовом уровне диска PostgreSQL использует неупорядоченные структуры диска для хранения данных.Это происходит потому, что PostgreSQL может поддерживать несколько копий строки в любой момент времени из-за семантики транзакций MVCC.У каждой строки есть xmin и xmax, детализирующие идентификатор транзакции создания и уничтожения текущей строки.Процесс автоочистки выполняет операции очистки записей-призраков.Индексы в PostgreSQL указывают на строки в структуре таблицы кучи.Этот набор слайдов подробно описывает процесс.В частности, вы захотите посмотреть на слайде 29, как происходит поиск b-дерева, и на 48-52, чтобы теоретически обсудить, как данные хранятся на диске.

В SQL Server вы получитезаписей на листовой странице, но только с четырьмя строками кластеризованный индекс будет иметь только один уровень индекса - уровень листа.Вы можете проверить это, запустив SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('dbo.Tree'), NULL, NULL, NULL).Вы также можете проверить уровень физической страницы в SQL Server, выполнив что-то вроде этого:

-- Locate the first page of the index
DBCC IND('test', 'Tree', 1);
GO
-- tell SQL Server to show DBCC output in the message page, not the SQL Server log
DBCC TRACEON (3604);
GO
-- look at nasty, dirty, on page data.
DBCC PAGE(test, 1,155,3);

Когда вы посмотрите на вывод DBCC PAGE, вы будете готовы меня ненавидеть.К концу вы должны увидеть четыре строки, которые выглядят примерно так:

Slot 0 Offset 0x60 Length 15

Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     Record Size = 15

Memory Dump @0x000000006D6FA060

0000000000000000:   10000c00 01000000 01000000 020000††††...............  

Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4

Key = 1                              

Slot 0 Column 2 Offset 0x8 Length 4 Length (physical) 4

ID = 1                               

Slot 0 Offset 0x0 Length 0 Length (physical) 0

KeyHashValue = (e2338e2f4a9f)  

Это фактические данные строки, поскольку SQL Server хранит их.Вы увидите несколько копий Key = 1 во всем выводе, а затем информацию об идентификаторе.Вспомогательную информацию для этих команд можно найти здесь .

Причина различий между PostgreSQL и SQL Server основана на реализации PostgreSQL MVCC.Поскольку в PostgreSQL у нас может быть несколько копий строки, более целесообразно хранить несколько копий данных на диске, а не изменять структуры вспомогательных индексов.Когда это возможно, PostgreSQL делает обновления только для кучи и выпускает обновления только для базовой таблицы.SQL Server делает то же самое и обновляет кластерный индекс (или кучу) только тогда, когда он может избежать обновления вспомогательных индексов.

2 голосов
/ 14 марта 2011

Ознакомьтесь с моим учебным курсом по индексированию SQL , если вы хотите узнать больше об индексировании в целом.

2 голосов
/ 14 марта 2011

Я знаю, что SQL Server может хранить данные строки на уровне листьев в кластерном индексе. Я считаю, что PostgreSQL не делает этого. Если да, то какова его парадигма хранения?

В отличие от SQL Server и других механизмов, PostgreSQL не хранит идентификатор транзакции, которая изменила запись в индексах, только в куче.

Индексы просто указывают в кучу (и хранят ctid соответствующей записи в качестве указателя строки и, следовательно, часть ключа).

Это означает, что для каждого запроса, даже если он может быть удовлетворен поиском по индексу, все равно следует выполнить поиск в куче, чтобы обеспечить видимость данных для текущей транзакции.

Таким образом, индексы покрытия не очень полезны в PostgreSQL: поскольку поиск в куче должен выполняться в любом случае, движок может просто взять все данные из кучи.

2 голосов
/ 14 марта 2011

Вы правы - Postgres не может делать то, что вы просите. Подробнее см. этот вопрос.

Кластеризацию строк можно выполнить с помощью команды CLUSTER, но это не сохранит кластеризацию данных после выполнения DML.

...