У меня есть большая таблица (потенциально миллионы строк), которая в своей наивной форме будет содержать много повторений, например ::100100
CREATE TABLE sales(
id INTEGER PRIMARY KEY AUTOINCREMENT,
salesperson TEXT,
customer TEXT
);
INSERT INTO sales VALUES(NULL, "Rod", "Acme");
INSERT INTO sales VALUES(NULL, "Jane", "Xyz Corp");
INSERT INTO sales VALUES(NULL, "Freddy", "Acme");
<... many more lines containing significant repetitions of each salesperson and each customer >
Я думаю, что знаю достаточно, что это не идеальный подход, когда я хочу выполнить такие запросы, как:
SELECT count(*) FROM sales WHERE salesperson="Jane";
Так что моя база данных должна быть переставлена как:
CREATE TABLE sales(
id INTEGER PRIMARY KEY AUTOINCREMENT,
salesperson INTEGER,
customer INTEGER
);
CREATE TABLE salespeople(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT
);
CREATE TABLE customers(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT
);
На самом деле в решении с одной таблицей гораздо больше столбцов и, следовательно, более четких таблиц в нормализованной (если это даже правильное использование термина) версии.
Я рассчитал тестирование глупого запроса по отношению к одной таблице v.s. СОЕДИНЕНИЕ с WHERE против версии с разделенными таблицами и «умной» версии примерно на 25% медленнее, поэтому ясно, что я что-то упускаю:
SELECT count(*) FROM sales INNER JOIN salespeople ON sales.salesperson=salespeople.id WHERE salespeople.name="Freddy";
Если я сначала посмотрю salesperson.id как отдельный запрос, я увижу время примерно на 33% быстрее, чем глупая реализация (что меньше, чем я ожидал).
SELECT id FROM salespeople WHERE name="Freddy";
... тогда
SELECT count(*) FROM sales WHERE salesperson=previouslyLookedUpId;
У меня складывается впечатление, что WHERE (в решении с несколькими таблицами) оценивается для каждой строки, а не один раз для определения соответствующего идентификатора продавца, как предполагалось. Очевидно, что мои запросы (или ограничения, или индексы?) Не позволяют эффективно работать с механизмом БД.
Я знаю только достаточно, чтобы знать, что не знаю достаточно ... Какой здесь правильный подход?