2012-06-07 2 views
0

у меня есть «входы» таблица, которая выглядит примерно так:Как объединить 2 MySQL запросов?

id subId surveyId name  val 
1 1  1  Ip Addr  123.456.789 
2 1  1  Cookie  abcdefghij 
3 1  1  Time  2012-06-05 22:14:30 
4 2  1  Ip Addr  123.456.789 
5 2  1  Time  2012-06-05 22:14:40 

subId короток для представления Id. Я хочу получить все сообщения с определенным survId через определенное время. Есть 2 шага. Во-первых, получите все идентификаторы отправки через определенное время. Это может быть достигнуто следующим образом:

SELECT subId FROM Inputs WHERE surveyId=1 AND name='Time' AND val>'2012-06-05 22:14:35'; 

Далее, получить все строки для этих представлений:

SELECT * FROM Inputs WHERE subId IN (...); 

Когда я заменить ... с результатами первого запроса, все работает отлично. Он возвращает последние 2 строки (id 4 и 5). Вот EXPLAIN запроса 1:

id select_type table type possible_keys key  key_len ref  rows Extra 
1 SIMPLE  Inputs range Inputs_ix1 Inputs_ix1 1030 (null) 3  Using where 

И запрос 2:

id select_type table type possible_keys key  key_len ref  rows Extra 
1 SIMPLE  Inputs range Inputs_ix2 Inputs_ix2 4  (null) 30  Using where 

Когда я их профиль, они занимают около 1 миллисекунды вместе на 10000 строк. Все идет нормально. Однако я хотел бы объединить их вместе. Вот что я пробовал:

SELECT * FROM Inputs WHERE subId IN (SELECT subId FROM Inputs WHERE surveyId=1 AND name='Time' AND val>'2012-06-05 22:14:35'); 

Это займет около 200 миллисекунд! Я думаю, это связано с bug. Так давайте попробуем что-то другое:

SELECT (@ids:=subId) FROM Inputs WHERE surveyId=1 AND name='Time' AND val>'2012-06-05 22:14:35'; 
SELECT @ids; 

Здесь я пытаюсь сделать @ids переменную с результатом первого запроса. Однако в переменной сохраняется только последний идентификатор. Переменные MySQL не работают с массивами ?!

Может ли кто-нибудь мне помочь?

ответ

0

Вы можете запустить его в качестве одного запроса: (замените «Subid» часть первых запросов с «*» и добавить «(NOLOCK)»)

SELECT * FROM Inputs (NOLOCK) WHERE surveyId=1 AND name='Time' AND val>'2012-06-05 22:14:35'; 

Другим вариант заключается в использовании INNER JOIN:

SELECT Inputs2.* 
FROM Inputs AS Inputs1 (NOLOCK) 
INNER JOIN Inputs AS Inputs2 (NOLOCK) 
ON Inputs1.subId = Inputs2.subId 
WHERE surveyId=1 
AND name='Time' 
AND val>'2012-06-05 22:14:35'; 

Я не знаю времени этих вариантов.

Удачи!

+0

Что именно делает '(NOLOCK)'? – Joel

+0

Это хит для механизма запросов. Он говорит, что он не блокирует таблицы при запуске запроса. См. Http://msdn.microsoft.com/en-us/library/ms187373.aspx. Он используется в производстве, позволяя одновременно запрашивать больше запросов к таблице. В противном случае движок позволяет только одному запросу обращаться к таблице за раз. – jneff

+0

Хорошо. '(NOLOCK)', похоже, не работает в моей настройке. Но запрос «INNER JOIN» отвечает на мой вопрос. Благодаря! – Joel

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