2016-12-15 4 views
-1

ich einen Blick in MySQLMySQL Ansicht Abfrage dauert sehr lange zum Laden

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` 
SQL SECURITY DEFINER VIEW `inventory_view` AS 
select (case when isnull(`a`.`items_sold`) then 0 else `a`.`items_sold` end) AS `sold_qty`, 
     (case when isnull(`a`.`items_bought`) then 0 else `a`.`items_bought` end) AS `bought_qty`, 
     (case when isnull(`a`.`credit`) then 0 else `a`.`credit` end) AS `credit_amount`, 
     (case when isnull(`a`.`debit`) then 0 else `a`.`debit` end) AS `debit_amount`, 
     (case when isnull(`tv`.`count`) then 0 else `tv`.`count` end) AS `tranfers`, 
     (case when isnull(`a`.`inhand`) then 0 else `a`.`inhand` end) AS `balance`, 
     (case when isnull(`tv`.`count`) then `a`.`inhand` when isnull(`a`.`inhand`) then `tv`.`count` else (`a`.`inhand` + `tv`.`count`) end) AS `in_hand`, 
     (case when isnull(`a`.`company_id`) then `tv`.`fk_company` else `a`.`company_id` end) AS `company`, 
     (case when isnull(`a`.`branch_id`) then `tv`.`fk_branch` else `a`.`branch_id` end) AS `branch`, 
     (case when isnull(`a`.`item_code`) then convert(`tv`.`fk_item_code` using utf8) else convert(`a`.`item_code` using utf8) end) AS `item`, 
     (case when isnull(`a`.`operator`) then `tv`.`user` else `a`.`operator` end) AS `fk_operator` 
from (`transfer_view` `tv` left join `inventory_main` `a` on(((convert(`tv`.`fk_item_code` using utf8) = convert(`a`.`item_code` using utf8)) and (`a`.`operator` = `tv`.`user`)))) 
union 
select (case when isnull(`a`.`items_sold`) then 0 else `a`.`items_sold` end) AS `sold_qty`, 
     (case when isnull(`a`.`items_bought`) then 0 else `a`.`items_bought` end) AS `bought_qty`, 
     (case when isnull(`a`.`credit`) then 0 else `a`.`credit` end) AS `credit_amount`, 
     (case when isnull(`a`.`debit`) then 0 else `a`.`debit` end) AS `debit_amount`, 
     (case when isnull(`tv`.`count`) then 0 else `tv`.`count` end) AS `tranfers`, 
     (case when isnull(`a`.`inhand`) then 0 else `a`.`inhand` end) AS `balance`, 
     (case when isnull(`tv`.`count`) then `a`.`inhand` when isnull(`a`.`inhand`) then `tv`.`count` else (`a`.`inhand` + `tv`.`count`) end) AS `in_hand`, 
     (case when isnull(`a`.`company_id`) then `tv`.`fk_company` else `a`.`company_id` end) AS `company`, 
     (case when isnull(`a`.`branch_id`) then `tv`.`fk_branch` else `a`.`branch_id` end) AS `branch`, 
     (case when isnull(`a`.`item_code`) then convert(`tv`.`fk_item_code` using utf8) else convert(`a`.`item_code` using utf8) end) AS `item`, 
     (case when isnull(`a`.`operator`) then `tv`.`user` else `a`.`operator` end) AS `fk_operator` 
from (`inventory_main` `a` left join `transfer_view` `tv` on(((convert(`tv`.`fk_item_code` using utf8) = convert(`a`.`item_code` using utf8)) and (`a`.`operator` = `tv`.`user`)))); 

Es hat Tausende von Datensätzen erstellt und führt sehr langsam. Jede Abfrage dauert etwa 50 Sekunden.

Können Sie mir bitte helfen, den Fehler zu finden oder eine bessere Möglichkeit zum Erstellen der Ansicht empfehlen?

+3

Poste das Ganze nicht in einer Zeile. Fügen Sie Zeilenumbrüche hinzu und ziehen Sie sie ein, damit wir sehen können, was sie macht. – Barmar

+1

Die Abfrage sagt uns nichts. Pls enthalten die EXPLAIN-Ergebnisse für die Auswahl und eine Liste aller Indizes und indizierten Spalten in den betroffenen Tabellen. Sie müssen uns auch mitteilen, was Sie aus dem Bericht herausholen möchten (Beispieldaten und die erwartete Ausgabe basierend auf den Beispieldaten wären eine große Hilfe). – Shadow

+0

Was macht die Ansicht? Was ist der Zweck dieser Abfrage? Sie müssen angeben, wofür Sie Hilfe benötigen, so dass die Personen Sie verstehen können, ohne Ihre Perspektive zu haben. Wir sind nicht allwissend in deinem Leben. –

Antwort

0

Erstellen Sie einen zusammengesetzten Index für den fk_item_code und den Benutzer von transfer_view.

Erstellen Sie einen zusammengesetzten Index für item_code und operator von inventory_main.

versuchen, einige Ihrer Aussagen zu verwenden coalesce wie diese Schalt:

create view inventory_view as 

select 
     coalesce(a.items_sold, 0) as sold_qty, 
     coalesce(a.items_bought, 0) as bought_qty, 
     coalesce(a.credit, 0) as credit_amount, 
     coalesce(a.debit, 0) as debit_amount, 
     coalesce(tv.count, 0) as transfers, 
     coalesce(a.inhand, 0) as balance, 
     coalesce(tv.count, 0) + coalesce(a.inhand, 0) as in_hand, 
     coalesce(a.company_id, tv.fk_company) as company, 
     coalesce(a.branch_id, tv.fk_branch) as branch, 
     convert(coalesce(a.item_code, tv.fk_item_code) using utf8) as item, 
     coalesce(a.operator, tv.user) as fk_operator 
from transfer_view tv 
left join inventory_main a 
     on convert(tv.fk_item_code using utf8) = convert(a.item_code using utf8) 
     and a.operator = tv.user 

union 

select 
     coalesce(a.items_sold, 0) as sold_qty, 
     coalesce(a.items_bought, 0) as bought_qty, 
     coalesce(a.credit, 0) as credit_amount, 
     coalesce(a.debit, 0) as debit_amount, 
     coalesce(tv.count, 0) as transfers, 
     coalesce(a.inhand, 0) as balance, 
     coalesce(tv.count, 0) + coalesce(a.inhand, 0) as in_hand, 
     coalesce(a.company_id, tv.fk_company) as company, 
     coalesce(a.branch_id, tv.fk_branch) as branch, 
     convert(coalesce(a.item_code, tv.fk_item_code) using utf8) as item, 
     coalesce(a.operator, tv.user) as fk_operator 
from inventory_main a 
left join transfer_view tv 
     on convert(tv.fk_item_code using utf8) = convert(a.item_code using utf8) 
     and a.operator = tv.user; 

Macht das die Performance der Abfrage?

Wenn nicht, hier sind die Schritte, die ich empfehlen:

  • finden passende Datensätze zwischen den beiden Tabellen
  • finden alle Datensätze aus transfer_view ohne passenden Datensätze in inventory_main
  • finden alle Datensätze aus inventory_main mit nein passende Datensätze in transfer_view
  • union all die drei Datensätze

Beispiel -

create view inventory_view as 

select 
    ... 
from transfer_view tv 
inner join inventory_main a 
    on tv.fk_item_code = a.item_code -- you can convert ONLY if you need 
    and a.operator = tv.user 

union all 

select 
    ... 
from transfer_view tv 
where not exists (
    select 1 from inventory_main 
    where item_code = tv.fk_item_code and operator = tv.user 
) 

union all 

select 
    ... 
from inventory_main a 
where not exists (
    select 1 from transfer_view 
    where fk_item_code = a.item_code and user = a.operator 
); 
Verwandte Themen