Да, я бы использовал индекс по столбцам, по которым вы группируете.Как я уже упоминал в комментариях, я бы также использовал один запрос, который генерирует все желаемые строки, более 1000 запросов, которые производят фрагмент общей суммы за штуку.Заставьте базу данных сделать все это только один раз.Так как вы упомянули имена, которые вас интересуют, это 1000 наиболее распространенных, а не случайных имен, что на самом деле делает это немного проще.
Следующее демонстрирует два несколько разных подхода к получению количества за (year, county, district, surname)
из наиболее распространенных фамилий в целом:
Сначала заполните таблицу некоторыми примерами данных:
CREATE TABLE census(year INTEGER, county TEXT, district TEXT, surname TEXT);
INSERT INTO census VALUES
(2012, 'Lake', 'West', 'Smith'),
(2012, 'Lake', 'West', 'Jones'),
(2012, 'Lake', 'West', 'Smith'),
(2012, 'Lake', 'West', 'Washington'),
(2012, 'Lake', 'West', 'Washington'),
(2012, 'Lake', 'East', 'Smith'),
(2012, 'Lake', 'East', 'Jackson'),
(2012, 'Williams', 'Downtown', 'Jones'),
(2012, 'Williams', 'Downtown', 'McMaster'),
(2012, 'Williams', 'West Side', 'Jones'),
(2012, 'Williams', 'West Side', 'Jones');
CREATE INDEX census_idx ON census(year, county, district, surname);
(Ваши реальные данные, конечно же, будут иметь гораздо больше строк и, вероятно, большестолбцы. В зависимости от ограниченного пространства вы можете удалить фамилию из индекса за счет более медленного запроса. Со всеми четырьмя столбцами в индексе это охватывающий индекс для запросов ниже и фактическийСтроки таблицы никогда не будут доступны. Только с первыми тремя (или двумя, или одним) потребуются временные b-деревья для группировки и больше обращений к таблице.).
Подход первый: заполнение временноготаблицу с 1000 наиболее распространенными именами в целом, и используйте эту таблицу в объединении, чтобы ограничить результаты только этими именами:
CREATE TEMP TABLE names(name TEXT PRIMARY KEY) WITHOUT ROWID;
INSERT INTO names
SELECT surname FROM census GROUP BY surname ORDER BY count(*) DESC LIMIT 1000;
SELECT year, county, district, surname, count(*) as number
FROM census AS c
JOIN names AS n ON c.surname = n.name
GROUP BY year, county, district, surname
ORDER BY year, county, district, count(*) DESC, surname;
Approach два: сделать то же самое, но подзапрос вместо таблицы для наиболее распространенных имен:
SELECT year, county, district, surname, count(*) as number
FROM census AS c
JOIN (SELECT surname AS name FROM census GROUP BY surname ORDER BY count(*) DESC LIMIT 1000) AS n ON c.surname = n.name
GROUP BY year, county, district, surname
ORDER BY year, county, district, count(*) DESC, surname;
Оба выдают:
year county district surname number
---------- ---------- ---------- ---------- ----------
2012 Lake East Jackson 1
2012 Lake East Smith 1
2012 Lake West Smith 2
2012 Lake West Washington 2
2012 Lake West Jones 1
2012 Williams Downtown Jones 1
2012 Williams Downtown McMaster 1
2012 Williams West Side Jones 2
Если вы собираетесь запустить этоЗапрашивать много в сеансе, первый подход будет быстрее - он должен составить список наиболее распространенных имен только один раз, в то время как второй должен делать это каждый раз, когда выполняется запрос.Это, однако, более сложным, потому что он принимает несколько операторов SQL.Для отдельного прогона, конечно, наилучшим ориентиром будет сравнение двух подходящих наборов данных.