2015-06-02 3 views
0

Так у меня есть таблицы, которые выглядят примерно так:SQL Вставка и выбор нескольких столбцов?

связи (звонки, сделанные)

Timestamp   FromIDNumber ToIDNumber GeneralLocation 
2012-03-02 09:02:30 878   674  Grasslands 
2012-03-02 11:30:01 456   213  Tundra 
2012-03-02 07:02:12 789   654  Mountains 
2012-03-02 08:06:08 458   789  Tundra 

И я хочу, чтобы создать новую таблицу, которая имеет все различные FromIDNumber и ToIDNumber «с.

Это SQL Fiddle для этого.

Это работает:

INSERT INTO CommIDTemp (`ID`) 
SELECT DISTINCT Communication.FromIDNumber 
FROM Communication 
UNION DISTINCT 
SELECT DISTINCT Communication.ToIDNumber 
FROM Communication; 

и я получил:

ID 
878 
456 
789 
674 
213 
654 
365 

Но мне интересно, если есть более эффективный способ, потому что набор данных, который у меня есть миллионы и миллионы строк, и я Бесполезный Не знаю о производительности UNION DISTINCT.

Первоначально я пытался что-то вроде

INSERT INTO CommIDTemp (`ID`) 
SELECT DISTINCT Communication.FromIDNumber 
AND Communication.ToIDNumber 
FROM Communication; 

, но это не работает ... есть ли другой способ сделать это более эффективно? Я довольно новичок в SQL, поэтому любая помощь будет очень признательна, спасибо!

+1

'A и B' попытается вставить логическое' AND' результат двух строк. 'select 'a' и 'b'' -> result =' 0'. –

+0

Ох .. Я не знал этого ... спасибо – ocean800

+0

Это одноразовая задача? Так что не имеет значения, сколько времени это займет? Что вы будете делать с добавлением новых значений по мере поступления большего количества данных? –

ответ

2

Первое: у меня нет опыта с этими большими столами. Таким образом, вы должны проверить следующие Tipps себя, чтобы выяснить, если они действительно работают в вашей ситуации:

1. Создание индекса в исходной таблице

Убедитесь, что обе колонки FromIDNumber и ToIDNumber имеют индекс, т.е.

ALTER TABLE Communication ADD INDEX (FromIDNumber); 
ALTER TABLE Communication ADD INDEX (ToIDNumber); 

2. Попробуйте удалить DISTINCT

Я не мог найти более быстрый запрос для вашего примера, хотя вы можете попробовать запрос без ключевого слова DISTINCT - используя UNION возвращает только определенные значения по определению.Так что SQL дает нам тот же результат, что и текущий запрос:

INSERT INTO CommIDTemp (`ID`) 
SELECT FromIDNumber FROM Communication 
UNION 
SELECT ToIDNumberFROM Communication; 

3. Использовать первичный ключ в таблице темпа

также попробовать другой подход, установив столбец CommIDTemp.ID в качестве основных ключ и использовать INSERT IGNORE - это особенно полезно, если вы хотите, чтобы обновить таблицу часто без удаления содержимого:

CREATE TABLE CommIDTemp (ID INT PRIMARY KEY); 

INSERT IGNORE INTO CommIDTemp (`ID`) 
SELECT FromIDNumber FROM Communication 
UNION 
SELECT ToIDNumber FROM Communication; 
+0

'UNION' по умолчанию' DISTINCT', так что это не будет иметь никакого значения. Другой вариант - «UNION ALL», но это может привести к дублированию. –

2

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

Вы можете сделать это быстрее, используя только один оператор DISTINCT. Для каждого DISTINCT требуется таблица sort/temp. Вы можете отбросить DISTINCT из каждого утверждения, а UNION DISTINCT будет удостовериться, что вы получите отличные значения.

INSERT INTO CommIDTemp (`ID`) 
SELECT Communication.FromIDNumber 
FROM Communication 
UNION DISTINCT 
SELECT Communication.ToIDNumber 
FROM Communication; 

Side Примечание: UNION ALL быстрее, чем UNION DISTINCT, но на основе ваших требований, вы должны UNION DISTINCT, которые могут быть записаны просто как UNION.

Смежные вопросы