Выберите людей с данной фамилией из базы данных - PullRequest
0 голосов
/ 31 декабря 2018

Я делаю следующее, чтобы получить население в ряде округов за данный год:

SELECT Year, County, District, Count(*) FROM census_data group by Year, County, District where Year = ?;

Затем я делаю следующее много тысяч раз, чтобы получить население в каждом районе для каждой фамилии IЯ заинтересован в:

SELECT Year, County, District, COUNT(*) FROM census_data where Year = ? and Surname = ? group by Year, County, District;

В моей базе данных есть 8 миллионов строк, охватывающих два конкретных года.Примерно 40 округов, а в округе обычно есть несколько сотен округов.

Должен ли я добавить индекс в свою таблицу, чтобы ускорить выполнение вышеуказанных запросов следующим образом:

CREATE INDEX surname_index ON census_data (surname);

Я думаю, чточто, поскольку, вообще говоря, людей с данной фамилией не так много, достаточно просто ее проиндексировать.Или вы бы порекомендовали что-то еще?Я мог бы также изменить запрос на:

SELECT Year, County, District, COUNT(*) FROM census_data where Surname = ? group by Year, County, District;

, так как в любом случае меня обычно интересуют оба года.Когда я делаю запросы, как мне узнать, используется ли мой индекс?

1 Ответ

0 голосов
/ 31 декабря 2018

Да, я бы использовал индекс по столбцам, по которым вы группируете.Как я уже упоминал в комментариях, я бы также использовал один запрос, который генерирует все желаемые строки, более 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.Для отдельного прогона, конечно, наилучшим ориентиром будет сравнение двух подходящих наборов данных.

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