"не является нулевым" против логического MySQL - производительность - PullRequest
11 голосов
/ 26 января 2012

У меня есть столбец с указанием даты и времени, converted_at.

Я планирую делать звонки, которые проверяют WHERE converted_at is not null очень часто. Поэтому я рассматриваю логическое поле converted. Существенная разница в производительности между проверкой, является ли поле not null против, если оно false?

Спасибо.

Ответы [ 3 ]

5 голосов
/ 26 января 2012

Если вещи подотчетны одному полю, вы предпочитаете разделять одно и то же на два поля.Это создает больше инфраструктуры, которую, в вашем случае, можно избежать.

Что касается сути вопроса, я считаю, что большая часть реализации базы данных, включая MySQL, будет иметь внутренний флаг, который в любом случае является логическим для представления NULLability ofполе.

Вы должны полагаться, что это сделано для вас правильно.

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

2 голосов
/ 26 января 2012

Использование WHERE converted_at is not null или WHERE converted = FALSE, вероятно, будет одинаковым в вопросах производительности запросов.

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

Поэтому я не думаю, что было бы хорошо добавить это битовое поле.

Если вы можете изменить рассматриваемый столбец с NULL на NOT NULL (возможно, нормализуя таблицу), вы можете получить некоторое повышение производительности (за счет увеличения / увеличения количества таблиц).

0 голосов
/ 14 ноября 2018

У меня был такой же вопрос для моего собственного использования.Поэтому я решил проверить это.Поэтому я создал все поля, необходимые для 3 представленных мною возможностей:

# option 1
ALTER TABLE mytable ADD deleted_at DATETIME NULL;
ALTER TABLE mytable ADD archived_at DATETIME NULL;

# option 2
ALTER TABLE mytable ADD deleted boolean NOT NULL DEFAULT 0;
ALTER TABLE mytable ADD archived boolean NOT NULL DEFAULT 0;

# option 3
ALTER TABLE mytable ADD invisibility TINYINT(1) UNSIGNED NOT NULL DEFAULT 0
            COMMENT '4 values possible' ;

Последнее - это битовое поле, в котором 1 = заархивировано, 2 = удалено, 3 = удалено + заархивировано

Первое отличие, вы должны создать индексы для optioon 2 и 3.

CREATE INDEX mytable_deleted_IDX USING BTREE ON mytable (deleted) ;
CREATE INDEX mytable_archived_IDX USING BTREE ON mytable (archived) ;

CREATE INDEX mytable_invisibility_IDX USING BTREE ON mytable (invisibility) ;

Затем я попробовал все варианты, используя реальный запрос SQL, для 13k записей в основной таблице, вот как это выглядит

SELECT *
FROM mytable
LEFT JOIN  table1 ON mytable.id_qcm = table1.id_qcm
LEFT JOIN  table2 ON table2.id_class = mytable.id_class
INNER JOIN  user ON mytable.id_user = user.id_user
where mytable.id_user=1  
and mytable.deleted_at is null  and mytable.archived_at is null
# and deleted=0    
# and invisibility=0  
order BY id_mytable

В качестве альтернативы используются параметры фильтра, указанные выше.
Используется mysql 5.7.21-1 debian9

Мой вывод:

"Это"null "решение (вариант 1) немного быстрее или, по крайней мере, с той же производительностью.

Два других («удалено = 0» и «невидимость = 0») кажутся в среднем немного медленнее.

Но опция обнуляемых полей имеет решающие преимущества: нет индекса для создания, проще для обновления, проще для запроса.И меньше места для хранения.

(кроме того, кроме того, вставки и обновления практически должны быть быстрее, поскольку mysql не нужно обновлять индексы, но вы никогда не сможете этого заметить).

Так что вам следуетиспользуйте необязательные поля данных.

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