代码之家  ›  专栏  ›  技术社区  ›  zzapper

为什么MySQL查询挂起?

  •  6
  • zzapper  · 技术社区  · 16 年前
    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';
    

    tbl\u order\u head 67000(30个字段)记录,tbl\u orders\u log 17000(5个字段)记录。我不知道它是否最终会返回,因为我在一个实时服务器上运行它,并且担心过载。

    我正在成功地进行类似的查询和更复杂的查询。

    tbl\订单\日志

    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
    

    索引信息

    Indexes Columns Index_Type
    PRIMARY ID Unique
    

    tbl\订单\头

    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
    

    嗨,我有(在帮助下) 重写了查询

    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');
    

    3 回复  |  直到 12 年前
        1
  •  2
  •   Aaron Digulla    16 年前

    因为有人锁了一张桌子或一行。例如,如果您在会话中禁用了自动提交(这样您就可以回滚所做的修改),而忘记在会话中提交,则可能会发生这种情况。

    This document 可能会有帮助。

    [编辑]发布表定义后,可以看到两个联接列的类型不同。现在的问题是:当您运行查询时,哪个类型将是向上/向下转换的?在您的情况下,最好使用 PAYMENT_TRANSACTION_LOG_ID 到 varchar ,尤其是当您在 TRANSACTION_ID (应为此查询创建)。

    tbl_order_head tbl_orders_log

        2
  •  1
  •   Greg K    16 年前

    你跑了吗 EXPLAIN

    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'
    

    您的联接可能会导致数百万/数十亿行被检查。您的表是否为此联接正确编制了索引?

        3
  •  0
  •   lugte098    16 年前

    我认为应该是o.TRANSACTION\u ID和c.PAYMENT\u TRANSACTION\u LOG\u ID,而不是c.TRANSACTION\u ID和o.PAYMENT\u TRANSACTION\u LOG\u ID。然后查询应该如下所示:

    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';