Оптимизация SQL для многостоловых запросов - PullRequest
0 голосов
/ 10 января 2011

Я работаю с большой базой данных о безработице, созданной из файлов, доступных в отделе статистики труда здесь:

ftp: //ftp.bls.gov/pub/time.series / la /

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

Мой первый запрос возвращает все подобласти в штате, для которых доступны данные по безработице.После добавления индексов в таблицу Series и таблицу Area время выполнения изменилось с 2 до 0,9 секунды, но я не могу его уменьшить.Я думаю, что DISTINCT делает это так долго, но необходимо, чтобы записи не возвращали дубликаты.

SELECT DISTINCT series.area_code, area.area_text FROM Alabama 
LEFT JOIN series ON Alabama.series_id=series.series_id 
LEFT JOIN area ON series.area_code=area.area_code
WHERE area.area_type_code != 'A';

Мой второй запрос, который фактически собирает данные для каждой из этих областей, занимает всего 0,3секунд, даже если он собирает гораздо больше записей:

USE unemploymentdata;
SELECT DISTINCT * FROM Alabama 
LEFT JOIN series ON Alabama.series_id=series.series_id 
LEFT JOIN area ON series.area_code=area.area_code
WHERE area.area_type_code != 'A' 
AND area.area_code = 'CA011420'
AND year > 2000;

У меня очень мало знаний об оптимизации базы данных и запросов на данный момент - кто-нибудь может дать мне какие-либо указатели на мои запросы или на добавление индексов и т. д.сама база данных для ускорения моих транзакций?

Ответы [ 3 ]

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

Возможно, ваша проблема в левом соединении. Вы хотели сделать это нормальным соединением? (Левое объединение вернет ноль, если в таблице справа нет соответствующих записей)

0 голосов
/ 10 января 2011
SELECT  DISTINCT 
        series.area_code, 
        area.area_text 
FROM    Alabama LEFT JOIN   
        series ON Alabama.series_id=series.series_id LEFT JOIN  
        area ON series.area_code=area.area_code
WHERE   area.area_type_code != 'A';

Можете ли вы заменить его на ВНУТРЕННЕЕ СОЕДИНЕНИЕ?

SELECT   DISTINCT 
         series.area_code, 
         area.area_text 
FROM     Alabama INNER JOIN 
         series ON Alabama.series_id=series.series_id INNER JOIN    
         area ON series.area_code=area.area_code
WHERE   area.area_type_code != 'A'

Нужен ли стол Алабама вообще? Получите ли вы те же результаты, если удалите его, как у меня здесь?

SELECT   DISTINCT 
         series.area_code, 
         area.area_text 
FROM     series INNER JOIN  
         area ON series.area_code = area.area_code
WHERE   area.area_type_code != 'A'

Тот же вопрос о таблице серий, можно ли ее удалить?

SELECT   DISTINCT 
         area.area_code, 
         area.area_text 
FROM     area 
WHERE   area.area_type_code != 'A'

Если нет, то это индексы.

Сначала таблица с областями. Добавьте индекс со следующими столбцами

area_type_code, area_code, area_text

таблица серий (тест быстрее).

series_id, area_code

или

area_code, series_id

стол Алабама создать простой индекс со следующим столбцом

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

Я предполагаю, что код города / текст медленно меняют данные, так почему бы не поместить их в свою собственную таблицу. Затем вы можете заменить их в таблице «Алабама» идентификатором, который уменьшит размер этой таблицы, что также ускорит чтение из этой таблицы.

Поскольку вы фактически не используете данные из таблицы Алабамы в первом запросе, это может быть быстрее без изменения таблицы.

SELECT DISTINCT series.area_code, area.area_text 
FROM  series
LEFT JOIN area ON series.area_code=area.area_code
WHERE area.area_type_code != 'A';
and series_id in (select series_id from Alabama)
...