Добавление одного подзапроса делает запрос немного медленнее, добавление другого - медленнее - PullRequest
0 голосов
/ 05 января 2011

Это быстро:

select ba.name,
penamt.value penamt,
#address_line4.value address_line4
from account a
join customer c on a.customer_id = c.id
join branch br on a.branch_id = br.id
join bank ba on br.bank_id = ba.id
join account_address aa on aa.account_id = a.id
join address ad on aa.address_id = ad.id
join state s on ad.state_id = s.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
join (select * from unused where heading_label = 'PENAMT') penamt ON penamt.account_id = a.id
#join (select * from unused where heading_label = 'Address Line 4') address_line4 ON address_line4.account_id = a.id
where i.active=1

И это быстро:

select ba.name,
#penamt.value penamt,
address_line4.value address_line4
from account a
join customer c on a.customer_id = c.id
join branch br on a.branch_id = br.id
join bank ba on br.bank_id = ba.id
join account_address aa on aa.account_id = a.id
join address ad on aa.address_id = ad.id
join state s on ad.state_id = s.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
#join (select * from unused where heading_label = 'PENAMT') penamt ON penamt.account_id = a.id
join (select * from unused where heading_label = 'Address Line 4') address_line4 ON address_line4.account_id = a.id
where i.active=1

Но это медленно:

select ba.name,
penamt.value penamt,
address_line4.value address_line4
from account a
join customer c on a.customer_id = c.id
join branch br on a.branch_id = br.id
join bank ba on br.bank_id = ba.id
join account_address aa on aa.account_id = a.id
join address ad on aa.address_id = ad.id
join state s on ad.state_id = s.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
join (select * from unused where heading_label = 'PENAMT') penamt ON penamt.account_id = a.id
join (select * from unused where heading_label = 'Address Line 4') address_line4 ON address_line4.account_id = a.id
where i.active=1

Почему это быстро, когда явключить только один из двух подзапросов, но медленно, когда я включаю оба?Я бы подумал, что это должно быть в два раза медленнее, когда я включаю оба, но это занимает очень много времени.Вкл на MySQL.

Вот EXPLAIN:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    19584   
1   PRIMARY a   eq_ref  PRIMARY,fk_account_branch_id,fk_account_customer_id,fk_account_import_id    PRIMARY 8   penamt.account_id   1   
1   PRIMARY br  eq_ref  PRIMARY,fk_branch_bank_id   PRIMARY 8   mcif.a.branch_id    1   
1   PRIMARY i   eq_ref  PRIMARY,import_bundle_id    PRIMARY 8   mcif.a.import_id    1   "Using where"
1   PRIMARY ba  eq_ref  PRIMARY PRIMARY 8   mcif.br.bank_id 1   
1   PRIMARY c   eq_ref  PRIMARY PRIMARY 8   mcif.a.customer_id  1   "Using index"
1   PRIMARY ib  eq_ref  PRIMARY PRIMARY 8   mcif.i.import_bundle_id 1   "Using index"
1   PRIMARY aa  ref fk_account_address_account_id,fk_account_address_address_id fk_account_address_account_id   8   mcif.a.id   1   "Using where"
1   PRIMARY <derived3>  ALL NULL    NULL    NULL    NULL    368367  "Using where; Using join buffer"
1   PRIMARY ad  eq_ref  PRIMARY,fk_account_state_id PRIMARY 8   mcif.aa.address_id  1   
1   PRIMARY s   eq_ref  PRIMARY PRIMARY 8   mcif.ad.state_id    1   "Using index"
3   DERIVED unused  ref heading_label   heading_label   257     469722  "Using where"
2   DERIVED unused  ref heading_label   heading_label   257     15632   "Using where"

Ответы [ 2 ]

1 голос
/ 06 января 2011

Не отвечает на ваш точный вопрос, но если вы измените свой запрос таким образом, чтобы полностью избавиться от подзапросов, я бы поспорил, что это будет значительно быстрее:

select ba.name,
penamt.value penamt,
address_line4.value address_line4
from account a
join customer c on a.customer_id = c.id
join branch br on a.branch_id = br.id
join bank ba on br.bank_id = ba.id
join account_address aa on aa.account_id = a.id
join address ad on aa.address_id = ad.id
join state s on ad.state_id = s.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
left join unused penamt on penamt.account_id = a.id and penamt.heading_label = 'PENAMT'
left join unused address_line4 on address_line4.account_id = a.id and address_line4.heading_label = 'Address Line 4'
where i.active=1
0 голосов
/ 06 января 2011

Похоже, вы ищете данные об исключениях ... те, в которых отсутствуют некоторые элементы, где ваши последние два запроса относятся к "неиспользуемой" таблице, ищущей индивидуально PEMAMT или адресную строку 4 в поле "heading_label". Кроме того, вы не получаете другую информацию, кроме той, которая имеется в отделении банка на счете клиента. Так зачем добавлять эти таблицы, если вы не будете получать другие данные, как только ваш запрос сработает ... При этом, я буду запрашивать ваши «исключительные» критерии заранее, ТОГДА присоединиться к таблице счетов. Использование предложения «STRAIGHT_JOIN» в верхней части указывает системе делать это в указанном порядке. Таким образом, предварительное требование должно быть выполнено в первую очередь и квалифицировать только те учетные записи, которые нуждаются в проверке / отсутствии данных. ТОГДА получите остальное ... Кроме того, во время предварительного запроса, если я ГРУППУЮ по максимуму ... и получу PENAMT и ADDRESS_LINE_4 в этом запросе, мне не нужно делать это снова в последующих соединениях ... Это квалифицировано ОДНАЖДЫ впереди.

Вот мой запрос на это.

select STRAIGHT_JOIN
      ba.name, 
      PreQuery.penamt, 
      PreQuery.address_line4
   from 
      ( SELECT account_id,
               MAX( CASE WHEN heading_label = 'PENAMT' 
                  THEN heading_label END ) penamt,
               MAX( CASE WHEN heading_label = 'Address Line 4' 
                  THEN heading_label END ) Address_line4
         from 
            unused
         where heading_label = 'PENAMT'
            OR heading_label = 'Address Line 4'
         group by 
            unused.account_id ) PreQuery
      join account a 
         ON PreQuery.account_id = a.id
      join customer c 
         on a.customer_id = c.id 
      join branch br 
         on a.branch_id = br.id 
      join bank ba 
         on br.bank_id = ba.id 
      join account_address aa 
         on a.id = aa.account_id
      join address ad 
         on aa.address_id = ad.id 
      join state s 
         on ad.state_id = s.id 
      join import i 
         on a.import_id = i.id 
      join import_bundle ib 
         on i.import_bundle_id = ib.id 
   where 
      i.active = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...