2010-04-07 14 views
6

tbl_order_head 67.000 (30 Felder) Datensätze, tbl_orders_log 17000 (5 Felder) Datensätze. Ich weiß nicht, ob es irgendwann zurückkehren würde, da ich es auf einem Live-Server betreibe und Angst vor Überlastung habe.Warum hängt diese MySQL-Abfrage?

Ich mache ähnliche Abfragen und viel komplexere Abfragen erfolgreich.

tbl_orders_log

Field Type Comment 
ID bigint(20) NOT NULL 
TRANSACTION_ID varchar(1000) NULL 
CREATED datetime NULL 
AMENDED datetime NULL 
PAYMENT_CARD_NUMBER varchar(255) NULL 
PAYMENT_CARD_TYPE varchar(255) NULL 
SESSION_ID varchar(255) NULL 
TRANSACTION_TYPE varchar(255) NULL 
TRANSACTION_VALUE varchar(255) NULL 
LOG_DATA text NULL 

Index Informationen

Indexes Columns Index_Type 
PRIMARY ID Unique 

tbl_order_head

CREATE TABLE `tbl_order_head` (
    `ID` varchar(255) NOT NULL, 
    `VISUAL_ID` decimal(20,0) DEFAULT NULL, 
    `CREATED` datetime DEFAULT NULL, 
    `AMENDED` datetime DEFAULT NULL, 
    `CUSTOMER_ID` varchar(255) DEFAULT NULL, 
    `BILLING_ID` varchar(255) DEFAULT NULL, 
    `ORDER_LINES_ITEM_VALUE` varchar(20) DEFAULT NULL, 
    `DELIVERY_VALUE` varchar(20) DEFAULT NULL, 
    `ORDER_LINES_ITEM_TAX` varchar(20) DEFAULT NULL, 
    `DELIVERY_TAX` varchar(20) DEFAULT NULL, 
    `DELIVERY_ALLOCATED_ITEMS_VALUE` varchar(20) DEFAULT NULL, 
    `DELIVERY_ALLOCATED_ITEMS_TAX` varchar(20) DEFAULT NULL, 
    `DELIVERY_ALLOCATED_ITEMS_TAX_DEDUCTION` varchar(20) DEFAULT NULL, 
    `DELIVERY_TAX_DEDUCTION` varchar(20) DEFAULT NULL, 
    `LOYALTY_CARD_POINTS_EARNED` varchar(10) DEFAULT NULL, 
    `LOYALTY_CARD_POINTS_REDEEMED` varchar(10) DEFAULT NULL, 
    `LOYALTY_CARD_POINTS_REDEEMED_VALUE` varchar(20) DEFAULT NULL, 
    `VOUCHER_CODE` varchar(50) DEFAULT NULL, 
    `AFFILIATE_CODE` varchar(50) DEFAULT NULL, 
    `LOYALTY_CARD_NUMBER` varchar(209) DEFAULT NULL, 
    `REDEEM_LOYALTY_CARD_POINTS` varchar(1) DEFAULT NULL, 
    `SOURCE` varchar(50) DEFAULT NULL, 
    `SKU_DATA` text, 
    `SKU_TAX_DATA` text, 
    `DISCOUNT_DATA` text, 
    `PAYMENT_CARD_TYPE` varchar(6) DEFAULT NULL, 
    `PAYMENT_CARD_NUMBER` varchar(255) DEFAULT NULL, 
    `PAYMENT_CARD_START_MONTH` varchar(6) DEFAULT NULL, 
    `PAYMENT_CARD_EXPIRY_MONTH` varchar(6) DEFAULT NULL, 
    `PAYMENT_CARD_START_YEAR` varchar(6) DEFAULT NULL, 
    `PAYMENT_CARD_EXPIRY_YEAR` varchar(6) DEFAULT NULL, 
    `PAYMENT_CARD_ISSUE_NUMBER` varchar(3) DEFAULT NULL, 
    `PAYMENT_CARD_SECURITY_NUMBER` varchar(4) DEFAULT NULL, 
    `PAYMENT_CARD_NAME` varchar(50) DEFAULT NULL, 
    `PAYMENT_CARD_SAVE` varchar(1) DEFAULT NULL, 
    `PAYMENT_CARD_CHARGE_AMOUNT` varchar(10) DEFAULT NULL, 
    `SAVED_PAYMENT_CARD_ID` varchar(255) DEFAULT NULL, 
    `SAVED_PAYMENT_CARD_SECURITY_NUMBER` varchar(255) DEFAULT NULL, 
    `GIFT_VOUCHER_DATA` text, 
    `GIFT_VOUCHER_APPLIED_VALUE` varchar(10) DEFAULT NULL, 
    `LOYALTY_EARNED_SKU_DATA` text, 
    `LOYALTY_REDEMPTION_SKU_DATA` text, 
    `LOYALTY_REDEMPTION_DEDUCTED_SKU_DATA` text, 
    `PAYMENT_CARD_AUTH_CODE` varchar(10) DEFAULT NULL, 
    `PAYMENT_TRANSACTION_LOG_ID` text, 
    `CREATED_BY` varchar(20) DEFAULT NULL, 
    `BASKET_ID` varchar(255) DEFAULT NULL, 
    `SKU_DESCRIPTION_XREF` text, 
    `IP_TRANSACTION_NUMBER` varchar(255) DEFAULT NULL, 
    `MEMS_BESPOKE_DISCOUNT_DATA` text, 
    `IP_EXPORTED` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`ID`), 
    KEY `CUSTOMER_ID` (`CUSTOMER_ID`,`CREATED`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

Hallo Ich habe (mit Hilfe) die Abfrage neu geschrieben

SELECT * FROM tbl_orders_log WHERE TRANSACTION_ID=(SELECT o.PAYMENT_TRANSACTION_LOG_ID FROM tbl_order_head AS o WHERE o.VISUAL_ID = '77783'); 

die sofort ausgeführt wird

+0

haben Sie Ihre Datenbank überprüft, wenn eine dieser Tabellen gesperrt ist? – hallie

Antwort

1

Weil jemand eine der Tabellen oder eine einzelne Zeile gesperrt hat. Dies kann beispielsweise der Fall sein, wenn Sie das automatische Commit in einer Sitzung deaktiviert haben (so dass Sie Ihre Änderungen rückgängig machen können) und vergessen haben, dort zu committen.

This document könnte helfen.

[EDIT] Nachdem Sie die Tabellendefinitionen veröffentlicht haben, können Sie sehen, dass die Typen der beiden Joinspalten unterschiedlich sind. Nun stellt sich die Frage: Welcher Typ wird beim Ausführen der Abfrage nach oben/unten gestellt? In Ihrem Fall ist es möglicherweise besser, den Typ PAYMENT_TRANSACTION_LOG_ID an varchar zu übergeben, insbesondere wenn Sie einen Index für TRANSACTION_ID haben (den Sie für diese Abfrage erstellen sollten).

Auf diese Weise werden einige Zeilen (oder sogar eine einzelne) aus der Tabelle tbl_order_head ausgewählt und dann findet eine schnelle Suche in der Tabelle tbl_orders_log statt. Ohne diese Option lädt die Datenbank alle Datensätze aus der Protokolltabelle und überprüft jeden Datensatz auf Übereinstimmung in den gefundenen Auftragskopfzeilen (plus jede ID auf den Typ in der Kopfzeile usw.).

+0

Hmm nie gedacht, aber ich führe die Abfrage von einer Konsole auf einem Live-Server. Ich denke, einzelne Datensätze könnten gesperrt werden, aber wie kann ich das beurteilen? und auf jeden Fall kann ich die einzelnen Tabellen sehen? – zzapper

+0

Siehe den Link, um Sperren und Deadlocks zu ermitteln. –

+0

Erstellt einen Index für TRANSACTION_ID und die Abfrage wurde sofort ausgeführt.So das löste mein Problem, danke – zzapper

1

Haben Sie in Ihrer Abfrage EXPLAIN ausgeführt, um den Abfrageplan anzuzeigen?

EXPLAIN SELECT * FROM tbl_order_head AS o INNER JOIN tbl_orders_log AS 
c ON o.PAYMENT_TRANSACTION_LOG_ID=c.TRANSACTION_ID WHERE o.VISUAL_ID = '77783' 

Ihr Join könnte dazu führen, dass Millionen/Milliarden von Zeilen untersucht werden. Sind Ihre Tabellen für diesen Join korrekt indiziert?

+0

Die Erklärung zurückgegeben "ID", "Select_type", "Tabelle", "Typ", "mögliches_Schlüssel", "Schlüssel", "key_len", "ref", "Zeilen", "Extra" "1", "EINFACH", "c", "ALLE", \ N, \ N, \ N, \ N, "16633", "" "1", "EINFACH", " o "," ALLES ", \ N, \ N, \ N, \ N," 59696 "," Verwendung wo " – zzapper

+0

Sieht aus, als würde es einen Tabellenscan durchführen (alle Zeilen untersuchen), es würde helfen, wenn Sie' SHOW CREATE 'hätten TABELLE

\ G' für beide Tabellen in dieser Abfrage und schließen Sie sie in Ihre Frage ein. –

+0

Ich kann jetzt sehen, dass die indizierten transaction_ids eine varchar (1000) und die andere bizarr ein Textfeld (Datenbank nicht von mir) – zzapper

0

Ich denke, es sollte o.TRANSACTION_ID und c.PAYMENT_TRANSACTION_LOG_ID anstelle von c.TRANSACTION_ID und o.PAYMENT_TRANSACTION_LOG_ID sein. Dann sollte die Abfrage wie folgt aussehen:

SELECT * FROM tbl_order_head o 
INNER JOIN tbl_orders_log c 
ON c.PAYMENT_TRANSACTION_LOG_ID=o.TRANSACTION_ID 
WHERE o.VISUAL_ID = '77783';