Magento Forum

   
Performancesteigerung im Backend durch SQL Optimierung
 
jschmahl
Jr. Member
 
Total Posts:  17
Joined:  2010-09-24
 

Hallo Community,

ich stehe vor einem kleinen Problem und wollte mal nachhören ob Jemand evt. schon einmal an dieser Sache gearbeitet hat und/oder Tipps und Tricks bereit hält dieses Problem aus der Welt zu schaffen.
Es geht um einen Webshop mit knappen 250 000 Kunden und ca. 1000 Produkten. Das Ganze ist eine Migration eines anderen Shops, aber das ist für die Sache irrelevant.

Problembereich: Backend
Problemberschreibung: Sehr langsame Zugriffszeiten auf die Kundenverwaltung (also die Liste/Grid)
Problemursache: nicht optimierte JOINs von Attributen

Soweit die Kurzfassung. Ich habe es schon soweit auseinnander nehmen können als das ich herausgefunden habe das die folgenden join aufrufe alle mit einem Filter versehen sind. Dadurch wird das Ganze aber erheblich langsamer als wenn man die Filteranweiseungen ins WHERE schieben würde. Leider habe ich bis jetzt nicht herausgefunden wie man dem Filter ein echtes NULL-Verhalten beibringen kann ohne das er sich die entity_id des Attributes holt.
Hat jemand von euch eine Idee oder gar schon etwas entwickelt oder kennt ein Modul welches diese Unzulänglichkeiten behebt?

Jetzt mal ein bisschen Quelltext:

protected function _prepareCollection()
    
{
        $collection 
Mage::getResourceModel('customer/customer_collection')
            ->
addNameToSelect()
            ->
addAttributeToSelect('email')
            ->
addAttributeToSelect('kundennummer')
            ->
addAttributeToSelect('pin')
            ->
addAttributeToSelect('created_at')
            ->
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'); 

        
$this->setCollection($collection);

        return 
parent::_prepareCollection();
    
}

... und ein bisschen SQL

SELECT
                
`e`.*,
                `
at_prefix`.`value` AS `prefix`,
                `
at_firstname`.`value` AS `firstname`,
                `
at_middlename`.`value` AS `middlename`,
                `
at_lastname`.`value` AS `lastname`,
                `
at_suffix`.`value` AS `suffix`,
                
CONCAT(
                               IF(
at_prefix.value IS NOT NULL AND at_prefix.value != '',CONCAT(LTRIM(RTRIM(at_prefix.value)),' '),''),
                               
LTRIM(RTRIM(at_firstname.value)),
                               
' ',
                               IF(
at_middlename.value IS NOT NULL AND at_middlename.value != '',CONCAT(LTRIM(RTRIM(at_middlename.value)),' '),''),
                               
LTRIM(RTRIM(at_lastname.value)),
                               IF(
at_suffix.value IS NOT NULL AND at_suffix.value != '',CONCAT(' ',LTRIM(RTRIM(at_suffix.value))),'')
                ) AS `
name`,
                `
at_default_billing`.`value` AS `default_billing`,
                `
at_billing_postcode`.`value` AS `billing_postcode`,
                `
at_billing_telephone`.`value` AS `billing_telephone`,
                `
at_billing_city_id`.`value` AS `billing_city_id`,
     
FROM `customer_entity` AS `e`
                
LEFT JOIN `customer_entity_varchar` AS `at_prefixON (`at_prefix`.`entity_id` = `e`.`entity_id`) AND (`at_prefix`.`attribute_id` = '4')
                
LEFT JOIN `customer_entity_varchar` AS `at_firstnameON (`at_firstname`.`entity_id` = `e`.`entity_id`) AND (`at_firstname`.`attribute_id` = '5')
                
LEFT JOIN `customer_entity_varchar` AS `at_middlenameON (`at_middlename`.`entity_id` = `e`.`entity_id`) AND (`at_middlename`.`attribute_id` = '6')
                
LEFT JOIN `customer_entity_varchar` AS `at_lastnameON (`at_lastname`.`entity_id` = `e`.`entity_id`) AND (`at_lastname`.`attribute_id` = '7')
                
LEFT JOIN `customer_entity_varchar` AS `at_suffixON (`at_suffix`.`entity_id` = `e`.`entity_id`) AND (`at_suffix`.`attribute_id` = '8')
                
LEFT JOIN `customer_entity_int` AS `at_default_billingON (`at_default_billing`.`entity_id` = `e`.`entity_id`) AND (`at_default_billing`.`attribute_id` = '13')
                
LEFT JOIN `customer_address_entity_varchar` AS `at_billing_postcodeON (`at_billing_postcode`.`entity_id` = `at_default_billing`.`value`) AND (`at_billing_postcode`.`attribute_id` = '30')
                
LEFT JOIN `customer_address_entity_varchar` AS `at_billing_telephoneON (`at_billing_telephone`.`entity_id` = `at_default_billing`.`value`) AND (`at_billing_telephone`.`attribute_id` = '31')
                
LEFT JOIN `customer_address_entity_varchar` AS `at_billing_country_idON (`at_billing_city_id`.`entity_id` = `at_default_billing`.`value`) AND (`at_billing_city_id`.`attribute_id` = '26'WHERE (`e`.`entity_type_id` = '1') AND (
                
CONCAT(
                               IF(
at_prefix.value IS NOT NULL AND at_prefix.value != ''CONCAT(LTRIM(RTRIM(at_prefix.value)),' '),''),
                               
LTRIM(RTRIM(at_firstname.value)),
                               
' ',
                               IF(
at_middlename.value IS NOT NULL AND at_middlename.value != '',CONCAT(LTRIM(RTRIM(at_middlename.value)), ' '),''),
                               
LTRIM(RTRIM(at_lastname.value)),
                               IF(
at_suffix.value IS NOT NULL AND at_suffix.value != '',CONCAT(' 'LTRIM(RTRIM(at_suffix.value))),'')
                )
LIKE '&#xna;chname%')
LIMIT 20;

 
Magento Community Magento Community
Magento Community
Magento Community
 
jschmahl
Jr. Member
 
Total Posts:  17
Joined:  2010-09-24
 

So sollte der SQL eher aussehen. Jedenfalls von der Perfomrance her.

SELECT
                
`e`.*,
                `
at_prefix`.`value` AS `prefix`,
                `
at_firstname`.`value` AS `firstname`,
                `
at_middlename`.`value` AS `middlename`,
                `
at_lastname`.`value` AS `lastname`,
                `
at_suffix`.`value` AS `suffix`,
                
CONCAT(
                               IF(
at_prefix.value IS NOT NULL AND at_prefix.value != '',CONCAT(LTRIM(RTRIM(at_prefix.value)),' '),''),
                               
LTRIM(RTRIM(at_firstname.value)),
                               
' ',
                               IF(
at_middlename.value IS NOT NULL AND at_middlename.value != '',CONCAT(LTRIM(RTRIM(at_middlename.value)),' '),''),
                               
LTRIM(RTRIM(at_lastname.value)),
                               IF(
at_suffix.value IS NOT NULL AND at_suffix.value != '',CONCAT(' ',LTRIM(RTRIM(at_suffix.value))),'')
                ) AS `
name`,
                `
at_default_billing`.`value` AS `default_billing`,
                `
at_billing_postcode`.`value` AS `billing_postcode`,
                `
at_billing_telephone`.`value` AS `billing_telephone`,
                `
at_billing_country_id`.`value` AS `billing_country_id`,
            
FROM
    
`customer_entity` AS `e`
                
LEFT JOIN `customer_entity_varchar` AS `at_prefixON (`at_prefix`.`entity_id` = `e`.`entity_id`)
                
LEFT JOIN `customer_entity_varchar` AS `at_firstnameON (`at_firstname`.`entity_id` = `e`.`entity_id`)
                
LEFT JOIN `customer_entity_varchar` AS `at_middlenameON (`at_middlename`.`entity_id` = `e`.`entity_id`)
                
LEFT JOIN `customer_entity_varchar` AS `at_lastnameON (`at_lastname`.`entity_id` = `e`.`entity_id`)
                
LEFT JOIN `customer_entity_varchar` AS `at_suffixON (`at_suffix`.`entity_id` = `e`.`entity_id`)
                
LEFT JOIN `customer_entity_int` AS `at_default_billingON (`at_default_billing`.`entity_id` = `e`.`entity_id`)
                
LEFT JOIN `customer_address_entity_varchar` AS `at_billing_postcodeON (`at_billing_postcode`.`entity_id` = `at_default_billing`.`value`)
                
LEFT JOIN `customer_address_entity_varchar` AS `at_billing_telephoneON (`at_billing_telephone`.`entity_id` = `at_default_billing`.`value`)
                
LEFT JOIN `customer_address_entity_varchar` AS `at_billing_city_idON (`at_billing_city_id`.`entity_id` = `at_default_billing`.`value`)
                
WHERE
                
(`e`.`entity_type_id` = '1')
                AND (`
at_prefix`.`attribute_id` = '4')
                AND (`
at_firstname`.`attribute_id` = '5')
                AND (`
at_middlename`.`attribute_id` = '6')
                AND (`
at_lastname`.`attribute_id` = '7')
                AND (`
at_suffix`.`attribute_id` = '8')
                AND (`
at_default_billing`.`attribute_id` = '13')
                AND (`
at_billing_postcode`.`attribute_id` = '30')
                AND (`
at_billing_telephone`.`attribute_id` = '31')
                AND (`
at_billing_city_id`.`attribute_id` = '26')
                AND (
                
CONCAT(
                               IF(
at_prefix.value IS NOT NULL AND at_prefix.value != ''CONCAT(LTRIM(RTRIM(at_prefix.value)),' '),''),
                               
LTRIM(RTRIM(at_firstname.value)),
                               
' ',
                               IF(
at_middlename.value IS NOT NULL AND at_middlename.value != '',CONCAT(LTRIM(RTRIM(at_middlename.value)), ' '),''),
                               
LTRIM(RTRIM(at_lastname.value)),
                               IF(
at_suffix.value IS NOT NULL AND at_suffix.value != '',CONCAT(' 'LTRIM(RTRIM(at_suffix.value))),'')
                )
LIKE '&#xna;chname%')
LIMIT 20;

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
    Back to top