Скорость запроса на основе порядка столбцов - PullRequest
9 голосов
/ 03 января 2011

Влияет ли порядок типов столбцов в вашей базе данных на время запроса?

Например, будет ли таблица со смешанным порядком (INT, TEXT, VARCHAR, INT, TEXT) медленнеезапрос, чем таблица с последовательными типами (INT, INT, VARCHAR, TEXT, TEXT)?

Ответы [ 4 ]

8 голосов
/ 18 января 2011

Ответ - да, это имеет значение, и это может иметь большое значение, но обычно не так много.

Все операции ввода-вывода выполняются на уровне страницы (обычно 2K или 4K в зависимости от вашей ОС). Данные столбцов для строк хранятся рядом друг с другом, за исключением случаев, когда страница заполняется, и в этом случае данные записываются на другой (обычно на следующей) странице.

Чем больше дискового пространства данных, необходимого для столбцов между (на основе определения таблицы) выбранными столбцами, тем больше вероятность того, что данные для выбранных столбцов будут (иногда) на разных страницах. Нахождение на другой странице может привести к дополнительной операции ввода-вывода (если на другой странице не выбраны другие строки). В худшем случае каждый выбранный вами столбец может находиться на отдельной странице.

Вот пример:

create table bad_layout (
num1 int,
large1 varchar(4000),
num2 int,
large2 varchar(4000),
num3 int,
large3 varchar(4000)
);

create table better_layout (
num1 int,
num2 int,
num3 int,
large1 varchar(4000),
large2 varchar(4000),
large3 varchar(4000)
);

Сравнение: выберите num1, num2, num3 из bad_layout; выберите num1, num2, num3 из better_layout;

Поскольку для bad_layout каждый столбец num в основном будет находиться на отдельной странице, для каждой строки потребуется 3 операции ввода-вывода. И наоборот, для better_layout столбцы num обычно находятся на одной странице.

Выполнение запроса bad_layout может занять в 3 раза больше времени.

Хорошая разметка таблицы может существенно повлиять на производительность запросов. Вы должны стараться, чтобы столбцы, которые обычно выбираются вместе, как можно ближе друг к другу в макете таблицы.

5 голосов
/ 03 января 2011

Заказ вряд ли будет иметь большое значение. Время выполнения определяется такими вещами, как время доступа к диску, а число и порядок обращений к диску вряд ли изменится в результате переупорядочения данных в строке.

Единственное исключение - если у вас в строке есть очень большой элемент (намного больше, чем дисковый блок, обычно 4 КБ?). Если у вас есть один очень большой столбец в таблице, вы можете поместить его в качестве последнего столбца, чтобы, если вы не обращаетесь к нему, его не нужно было полностью разбирать на страницы. Но даже тогда вам придется очень усердно работаю над созданием набора данных и схемы доступа, где разница будет заметна.

3 голосов
/ 03 января 2011

В PostgreSQL вы получите преимущество, если сначала поместите столбцы фиксированной ширины, поскольку этот путь доступа специально оптимизирован. Таким образом (INT, INT, VARCHAR, TEXT, TEXT) будут самыми быстрыми (относительный порядок VARCHAR и TEXT не имеет значения).

Кроме того, вы можете сэкономить место, что может повысить пропускную способность и производительность, если вы правильно управляете требованиями к выравниванию типов. Например, (INT, BOOL, INT, BOOL) потребуется 13 байт, потому что третий столбец должен быть выровнен на границе 4 байта, и поэтому между вторым и третьим столбцом будет потеряно 3 байта , Лучше бы здесь было (INT, INT, BOOL, BOOL). (Что бы ни последовало после этой строки, вероятно, также потребуется выравнивание по крайней мере 4 байта, поэтому вы потратите 2 байта в конце.)

0 голосов
/ 19 января 2011

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

PostgreSQL: http://social.msdn.microsoft.com/Forums/en-US/sqldatabaseengine/thread/a7ce8a90-22fc-456d-9f56-4956c42a78b0

SQL Server: http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/thread/36713a82-315d-45ef-b74e-5f342e0f22fa

Я подозреваю, что то же самое для MySQL.

Все данные читаются в страницах, поэтому, если ваши данные помещаются на одной странице, не имеет значения, как вы упорядочите столбцы.Если размер дискового блока составляет 2K, 4K, он будет кратен, чтобы удовлетворить «запрос страницы 8K».Если размер дискового блока составляет 64 КБ (для систем с большими БД), вы уже буферизуете другие данные.

Мало того, что при запросе записи он обычно извлекает все страницы для записи, включаяПереполнение страниц 2 и 3, если данные охватывают несколько страниц.Затем столбцы обрабатываются на основе полученных данных.SQL Server имеет ограничение на количество данных на странице, которое составляет около 8060 байт.Все, что больше, хранится на главной странице данных, подобно TOAST для PostgreSQL, и не извлекается, если столбец не используется. все еще не имеет значения, где находится столбец в порядке.

Например, в SQL Server несколько битовых полей хранятся вместе в маске с битовым рисунком - это независимо от того, положили ли выстолбцы рядом друг с другом.Я подозреваю, что MySQL и PostgreSQL делают одно и то же для оптимизации пространства.

Примечание: [существенное] - единственная причина этой квалификации заключается в том, что, возможно, при извлечении определенного столбца из страницы данныхналичие его в начале помогает, потому что вызовам низкоуровневой сборки не нужно искать далеко в блоке памяти.

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