Lưới khách hàng tùy chỉnh gây ra quét bảng và tập tin MySQL hay còn gọi là hiệu năng chậm


8

EDIT: Tôi đã có câu hỏi này ban đầu được đăng trên Stackoverflow mà không bao giờ được trả lời đầy đủ, tôi đang đăng ở đây với hy vọng sẽ làm sáng tỏ thêm lý do tại sao bảng khổng lồ quét và bất kỳ phương tiện nào để ngăn chặn những thay đổi cốt lõi tối thiểu (hy vọng).


Doanh nghiệp Magento. 1.10.1.1. Tập dữ liệu của khách hàng và địa chỉ là CSR bán lớn (125k +) thường nằm trên lưới này (đôi khi 25+ người dùng đồng thời tại một thời điểm).

Đây là đoạn mã là bộ sưu tập đang được tạo trong Grid.php Blocktệp Khách hàng . Không có gì lạ mắt hoặc khác thường, chỉ cần thêm thuộc tính vào bộ sưu tập là chủ yếu.

$collection = Mage::getResourceModel('customer/customer_collection')
    ->addNameToSelect()
    ->addAttributeToSelect('email')
    ->addAttributeToSelect('group_id')
    ->addAttributeToSelect('prod_codes')
    ->addAttributeToSelect('last_called_date')
    ->addAttributeToSelect('time_zone')
    ->addAttributeToSelect('salesrep')
    ->addAttributeToSelect('do_not_call')
    ->addAttributeToSelect('club_member')
    ->addAttributeToSelect('call_back_date')
    ->addAttributeToSelect('marketing_code_outcome')
    ->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
    ->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
    ->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')
    ->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left');

$this->setCollection($collection);

Tạo truy vấn này, hoạt động sai gây ra thời gian tải rất dài khi ở trong lưới khách hàng:

SELECT 
    e . *,
    _table_prefix.value AS prefix,
    _table_firstname.value AS firstname,
    _table_middlename.value AS middlename,
    _table_lastname.value AS lastname,
    _table_suffix.value AS suffix,
    CONCAT(IF(_table_prefix.value IS NOT NULL AND _table_prefix.value != '',
                CONCAT(TRIM(_table_prefix.value), ' '),
                ''),
            TRIM(_table_firstname.value),
            IF(_table_middlename.value IS NOT NULL AND _table_middlename.value != '',
                CONCAT(' ', TRIM(_table_middlename.value)),
                ''),
            ' ',
            TRIM(_table_lastname.value),
            IF(_table_suffix.value IS NOT NULL AND _table_suffix.value != '',
                CONCAT(' ', TRIM(_table_suffix.value)),
                '')) AS name,
    _table_default_billing.value AS default_billing,
    _table_billing_postcode.value AS billing_postcode,
    _table_billing_city.value AS billing_city,
    _table_billing_telephone.value AS billing_telephone,
    _table_billing_region.value AS billing_region
FROM
    customer_entity AS e
        LEFT JOIN
    customer_entity_varchar AS _table_prefix ON (_table_prefix.entity_id = e.entity_id) AND (_table_prefix.attribute_id = '4')
        LEFT JOIN
    customer_entity_varchar AS _table_firstname ON (_table_firstname.entity_id = e.entity_id) AND (_table_firstname.attribute_id = '5')
        LEFT JOIN
    customer_entity_varchar AS _table_middlename ON (_table_middlename.entity_id = e.entity_id) AND (_table_middlename.attribute_id = '6')
        LEFT JOIN
    customer_entity_varchar AS _table_lastname ON (_table_lastname.entity_id = e.entity_id) AND (_table_lastname.attribute_id = '7')
        LEFT JOIN
    customer_entity_varchar AS _table_suffix ON (_table_suffix.entity_id = e.entity_id) AND (_table_suffix.attribute_id = '8')
        LEFT JOIN
    customer_entity_int AS _table_default_billing ON (_table_default_billing.entity_id = e.entity_id) AND (_table_default_billing.attribute_id = '13')
        LEFT JOIN
    customer_address_entity_varchar AS _table_billing_postcode ON (_table_billing_postcode.entity_id = _table_default_billing.value) AND (_table_billing_postcode.attribute_id = '29')
        LEFT JOIN
    customer_address_entity_varchar AS _table_billing_city ON (_table_billing_city.entity_id = _table_default_billing.value) AND (_table_billing_city.attribute_id = '25')
        LEFT JOIN
    customer_address_entity_varchar AS _table_billing_telephone ON (_table_billing_telephone.entity_id = _table_default_billing.value) AND (_table_billing_telephone.attribute_id = '30')
        LEFT JOIN
    customer_address_entity_varchar AS _table_billing_region ON (_table_billing_region.entity_id = _table_default_billing.value) AND (_table_billing_region.attribute_id = '27')
WHERE
    (e.entity_type_id = '1')
ORDER BY CONCAT(IF(_table_prefix.value IS NOT NULL AND _table_prefix.value != '',
            CONCAT(TRIM(_table_prefix.value), ' '),
            ''),
        TRIM(_table_firstname.value),
        IF(_table_middlename.value IS NOT NULL AND _table_middlename.value != '',
            CONCAT(' ', TRIM(_table_middlename.value)),
            ''),
        ' ',
        TRIM(_table_lastname.value),
        IF(_table_suffix.value IS NOT NULL AND _table_suffix.value != '',
            CONCAT(' ', TRIM(_table_suffix.value)),
            '')) desc
LIMIT 20 OFFSET 60

một EXPLAINtruy vấn hiển thị, GHI CHÚ Bổ sung trên bảng e, Sử dụng tạm thời và Sử dụng tệp :

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: e
         type: ref
possible_keys: IDX_ENTITY_TYPE
          key: IDX_ENTITY_TYPE
      key_len: 2
          ref: const
         rows: 55556
        Extra: Using temporary; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_prefix
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_VARCHAR_ATTRIBUTE,FK_CUSTOMER_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod.e.entity_id,const
         rows: 1
        Extra:
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_firstname
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_VARCHAR_ATTRIBUTE,FK_CUSTOMER_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod.e.entity_id,const
         rows: 1
        Extra:
*************************** 4. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_middlename
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_VARCHAR_ATTRIBUTE,FK_CUSTOMER_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod.e.entity_id,const
         rows: 1
        Extra:
*************************** 5. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_lastname
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_VARCHAR_ATTRIBUTE,FK_CUSTOMER_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod.e.entity_id,const
         rows: 1
        Extra:
*************************** 6. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_suffix
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_VARCHAR_ATTRIBUTE,FK_CUSTOMER_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod.e.entity_id,const
         rows: 1
        Extra:
*************************** 7. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_default_billing
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_INT_ATTRIBUTE,FK_CUSTOMER_INT_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod.e.entity_id,const
         rows: 1
        Extra:
*************************** 8. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_billing_postcode
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_ADDRESS_VARCHAR_ATTRIBUTE,FK_CUSTOMER_ADDRESS_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod._table_default_billing.value,const
         rows: 1
        Extra:
*************************** 9. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_billing_city
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_ADDRESS_VARCHAR_ATTRIBUTE,FK_CUSTOMER_ADDRESS_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod._table_default_billing.value,const
         rows: 1
        Extra:
*************************** 10. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_billing_telephone
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_ADDRESS_VARCHAR_ATTRIBUTE,FK_CUSTOMER_ADDRESS_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod._table_default_billing.value,const
         rows: 1
        Extra:
*************************** 11. row ***************************
           id: 1
  select_type: SIMPLE
        table: _table_billing_region
         type: eq_ref
possible_keys: IDX_ATTRIBUTE_VALUE,FK_CUSTOMER_ADDRESS_VARCHAR_ATTRIBUTE,FK_CUSTOMER_ADDRESS_VARCHAR_ENTITY,IDX_VALUE
          key: IDX_ATTRIBUTE_VALUE
      key_len: 6
          ref: prod._table_default_billing.value,const
         rows: 1
        Extra:
11 rows in set (0.00 sec)

Không có chỉ mục nào được sửa đổi ngoài những chỉ số mặc định từ chính Magento cho 1.10.1 Xem Cấu trúc của 1.5.1 (CE) tại đây: http://www.magereverse.com/index/magento-sql-structure/version/1- 5-1-0

Dưới đây là bảng bí danh được gọi là AS e. khi quét:

CREATE TABLE `customer_entity` (
    `entity_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `entity_type_id` SMALLINT(8) UNSIGNED NOT NULL DEFAULT '0',
    `attribute_set_id` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
    `website_id` SMALLINT(5) UNSIGNED NULL DEFAULT NULL,
    `email` VARCHAR(255) NOT NULL DEFAULT '',
    `group_id` SMALLINT(3) UNSIGNED NOT NULL DEFAULT '0',
    `increment_id` VARCHAR(50) NOT NULL DEFAULT '',
    `store_id` SMALLINT(5) UNSIGNED NULL DEFAULT '0',
    `created_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
    `updated_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
    `is_active` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
    PRIMARY KEY (`entity_id`),
    INDEX `FK_CUSTOMER_ENTITY_STORE` (`store_id`),
    INDEX `IDX_ENTITY_TYPE` (`entity_type_id`),
    INDEX `IDX_AUTH` (`email`, `website_id`),
    INDEX `FK_CUSTOMER_WEBSITE` (`website_id`),
    CONSTRAINT `FK_CUSTOMER_ENTITY_STORE` FOREIGN KEY (`store_id`) REFERENCES `core_store` (`store_id`) ON UPDATE CASCADE ON DELETE SET NULL,
    CONSTRAINT `FK_CUSTOMER_WEBSITE` FOREIGN KEY (`website_id`) REFERENCES `core_website` (`website_id`) ON UPDATE CASCADE ON DELETE SET NULL
)

Vì vậy, câu hỏi là làm thế nào tôi có thể có được truy vấn này để thực hiện tốt hơn và không khiến các bảng tạm thời được tạo và quét.

Tôi không chắc chắn chính xác những gì tôi có thể lập chỉ mục để cải thiện hiệu suất truy vấn này và tôi không muốn đào sâu quá nhiều vào việc sửa đổi ORM của Magento.

Câu trả lời:


2

Câu trả lời cho hoàn cảnh của bạn không nằm trong các tùy chỉnh, chúng chỉ là tốt. Phần có vấn đề của truy vấn là ĐẶT HÀNG B andNG và sẽ chỉ đứng sau phần đầu xấu xí khi lưới được sắp xếp theo cột Tên trong quản trị viên:

ORDER BY CONCAT(IF(_table_prefix.value IS NOT NULL AND _table_prefix.value != '',
        CONCAT(TRIM(_table_prefix.value), ' '),
        ''),
    TRIM(_table_firstname.value),
    IF(_table_middlename.value IS NOT NULL AND _table_middlename.value != '',
        CONCAT(' ', TRIM(_table_middlename.value)),
        ''),
    ' ',
    TRIM(_table_lastname.value),
    IF(_table_suffix.value IS NOT NULL AND _table_suffix.value != '',
        CONCAT(' ', TRIM(_table_suffix.value)),
        '')) DESC

Mệnh đề ORDER BY này là cần thiết để sắp xếp theo cột Tên vì cột Tên là sự ghép nối của tiền tố, tên đầu tiên, tên đệm và tên cuối cùng của khách hàng. Để kết hợp thông tin và sử dụng nó để đặt hàng, một bảng tmp phải được sử dụng do dữ liệu được nối với nhau có nguồn gốc từ THAM GIA trên truy vấn. Đây là cách lõi Magento xử lý loại này, bởi vì nó chỉ áp dụng cùng một mã được sử dụng trong mệnh đề WHERE để áp dụng các loại.

Việc gói toàn bộ truy vấn dưới dạng một lựa chọn phụ sẽ giảm thời gian truy vấn xuống một chút, vì nó sẽ không sử dụng bảng tạm thời nữa, nhưng nó vẫn sẽ sử dụng các tệp.

Vì vậy, có hai "giải pháp" mà tôi có thể thấy ở đây:

  1. Tạo một thuộc tính full_name trên thực thể khách hàng được điền khi lưu. Thuộc tính full_name được điền trước này có thể được sử dụng trên lưới mà không cần bất kỳ hình thức nối nào và sẽ cắt bỏ sự cần thiết cho cả bảng tạm thời và tệp tin.

  2. Đơn giản là không sắp xếp theo cột Tên khi thời gian là một vấn đề. Điều này rõ ràng sẽ không hữu ích nếu bạn cần sắp xếp theo Tên, nhưng cần lưu ý cho đến khi bạn có cơ hội xây dựng các thay đổi trong # 1 ở trên. :)


Cảm ơn bạn đã phản hồi và làm rõ về ORDER BYmệnh đề và sự tham gia của tiền tố đầu tiên, họ, tiền tố. Kế hoạch ban đầu của tôi chỉ đơn giản là san phẳng khách hàng, bảng địa chỉ và viết lại một số logic, hai tùy chọn khác này nghe có vẻ nhanh hơn và dễ thực hiện hơn. cảm ơn lần nữa
B00mer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.