Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何提高此joomla查询的性能?_Mysql_Joomla2.5_Database Performance - Fatal编程技术网

Mysql 如何提高此joomla查询的性能?

Mysql 如何提高此joomla查询的性能?,mysql,joomla2.5,database-performance,Mysql,Joomla2.5,Database Performance,我正在尝试将一些joomla用户数据传递给Datatable(jQuery插件)。 涉及到4个表 joo_用户(~10k行) joo_用户组(~1.7k行) joo\u user\u usergroup\u map(~56k行) joo\u用户配置文件(~1398k行) 现在查询: SELECT SQL_CALC_FOUND_ROWS a.id, a.name, MAX( IF(profiles.profile_key = 'profile.email', profi

我正在尝试将一些joomla用户数据传递给Datatable(jQuery插件)。 涉及到4个表

  • joo_用户
    (~10k行)
  • joo_用户组
    (~1.7k行)
  • joo\u user\u usergroup\u map
    (~56k行)
  • joo\u用户配置文件
    (~1398k行)
现在查询:

SELECT SQL_CALC_FOUND_ROWS
    a.id,
    a.name,
    MAX( IF(profiles.profile_key = 'profile.email', profiles.profile_value, NULL) ) AS email,
    MAX( IF(profiles.profile_key = 'profile.codice_agente', profiles.profile_value, NULL) ) AS codice_agente,
    MAX( IF(profiles.profile_key = 'profile.codice_agente_fisso', profiles.profile_value, NULL) ) AS codice_agente_fisso,
    MAX( IF(profiles.profile_key = 'profile.codice_agente_VAR', profiles.profile_value, NULL) ) AS codice_agente_VAR,
    MAX( IF(profiles.profile_key = 'profile.cellulare', profiles.profile_value, NULL) ) AS cellulare,
    (SELECT
       GROUP_CONCAT(DISTINCT b.title)
    FROM
       joo_user_profiles AS up
    LEFT JOIN
       joo_usergroups AS b ON REPLACE(up.profile_value, '"', '') = b.id
    WHERE
       up.profile_key LIKE 'profile.agenzia_%'
       AND up.user_id = a.id
       AND profile_value != '""') AS agenzia,
   GROUP_CONCAT(DISTINCT REPLACE(IF(profiles.profile_key LIKE 'profile.canale_%' AND profiles.profile_value = '1', profiles.profile_key, NULL),'profile.canale_','') ) AS canale,
   GROUP_CONCAT(DISTINCT IF(profiles.profile_key LIKE 'profile.area_%' AND profiles.profile_value != '""', profiles.profile_value, NULL))  AS area,
   (SELECT
        GROUP_CONCAT(DISTINCT b.title)
        FROM
           joo_user_profiles AS up
        LEFT JOIN
           joo_usergroups AS b ON REPLACE(up.profile_value, '"', '') = b.id
        WHERE
           up.profile_key LIKE 'profile.ruolo_%'
           AND up.user_id = a.id
           AND profile_value != '"0"') AS ruolo,
    GROUP_CONCAT(IF(profiles.profile_key LIKE 'profile.status_%' AND profiles.profile_value != '""', profiles.profile_value, NULL))  AS status

    FROM   `joo_users` as a
    LEFT JOIN joo_user_profiles AS profiles ON a.id = profiles.user_id

    GROUP BY id

    ORDER BY  id
          asc
    LIMIT 0, 20
这个beast在生产服务器上需要40秒,这是不可接受的

我知道视图不会带来任何性能提升,我已经为我能想到的每一列建立了索引。
你有什么建议吗?

我不知道你为什么需要计算行,但把它放在那里了。 至于查询,由于您的所有组_concat都主要针对概要文件表和可选的用户组,因此我做了一个预查询(通过tmpGrpCat别名),仅使用相应的组_concat和max()对电子邮件、条件…、单元格、,等。我还将其包括在预查询中,以排除配置文件值不是“”的情况,因为对于您感兴趣的值来说,这似乎是一致的

然后,我在users表上做了一个简单的左连接,以获取他们的id/name和其他聚合。这应该可以简化引擎,让它对每个profile_key LIKE(或equality)条件的所有记录运行一次,按用户ID对它们进行分组,然后准备进行最外层的查询

如果这有效,请让我们了解性能改进。If将来也可以在性能技术方面帮助他人

SELECT SQL_CALC_FOUND_ROWS
      a.id,
      a.name,
      coalesce( tmpGrpCat.email, '' ) as email,
      coalesce( tmpGrpCat.codice_agente, '' ) as codice_agente,
      coalesce( tmpGrpCat.codice_agente_fisso, '' ) as codice_agente_fisso,
      coalesce( tmpGrpCat.codice_agente_VAR, '' ) as codice_agente_VAR,
      coalesce( tmpGrpCat.cellulare, '' ) as cellulare,
      coalesce( tmpGrpCat.AgTitle, '' )  as Agenzia,
      coalesce( tmpGrpCat.RuoloTitle, '' )  as ruolo,
      coalesce( tmpGrpCat.Canale, '' )  as Canale,
      coalesce( tmpGrpCat.Area, '' )  as Area,
      coalesce( tmpGrpCat.Status, '' )  as Status
   FROM   
      joo_users as a
         LEFT JOIN 
         ( SELECT 
                 up.user_id,
                 GROUP_CONCAT( DISTINCT IF( up.profile_key LIKE 'profile.agenzia_%', b.title, NULL )) AgTitle,
                 GROUP_CONCAT( DISTINCT IF( up.profile_key LIKE 'profile.ruolo_%', b.title, NULL )) RuoloTitle,
                 GROUP_CONCAT( DISTINCT IF( up.profile_key LIKE 'profile.canale_%' AND up.profile_value = '1', 
                    REPLACE( up.profile_key, 'profile.canale_',''), NULL)) AS canale,
                 GROUP_CONCAT( DISTINCT IF( up.profile_key LIKE 'profile.area_%', 
                    up.profile_value, NULL))  AS area,
                 GROUP_CONCAT( DISTINCT IF( up.profile_key LIKE 'profile.status_%', 
                    up.profile_value, NULL))  AS status,
                 MAX( IF( up.profile_key = 'profile.email', up.profile_value, NULL) ) AS email,
                 MAX( IF( up.profile_key = 'profile.codice_agente', up.profile_value, NULL) ) AS codice_agente,
                 MAX( IF( up.profile_key = 'profile.codice_agente_fisso', up.profile_value, NULL) ) AS codice_agente_fisso,
                 MAX( IF( up.profile_key = 'profile.codice_agente_VAR', up.profile_value, NULL) ) AS codice_agente_VAR,
                 MAX( IF( up.profile_key = 'profile.cellulare', up.profile_value, NULL) ) AS cellulare
              FROM 
                 joo_user_profiles AS up
                    LEFT JOIN joo_usergroups AS b 
                       ON REPLACE(up.profile_value, '"', '') = b.id
                    WHERE
                        ( up.profile_key LIKE 'profile.agenzia_%'
                       OR up.profile_key LIKE 'profile.ruolo_%' 
                       OR up.profile_key LIKE 'profile.canale_%'
                       OR up.profile_key LIKE 'profile.area_%' 
                       OR up.profile_key LIKE 'profile.status_%'
                       OR up.profile_key = 'profile.email'
                       OR up.profile_key = 'profile.codice_agente'
                       OR up.profile_key = 'profile.codice_agente_fisso'
                       OR up.profile_key = 'profile.codice_agente_VAR'
                       OR up.profile_key = 'profile.cellulare' )
                       AND up.profile_value != '""' 
                       AND up.profile_value != '"0"'
                    GROUP BY
                       up.user_id ) as tmpGrpCat
            ON a.id = tmpGrpCat.user_id
   ORDER BY  
      id asc
   LIMIT 
      0, 20

由于您是在Joomla中执行此查询,因此可以尝试使用Tabulizer for Joomla(),它可以通过使用数据源缓存(用于查询结果)和ajax加载来处理大数据集,因此最初只提取表的第一页,只有在需要时才提取其余数据。当然,查询需要至少执行一次才能填充缓存,因此您必须进一步改进它或增加可用的系统资源(PHP内存和最大执行时间)。这很可能是它在服务器上而不是本地服务器上失败的原因,因为大多数共享托管环境的PHP脚本执行时间最长为30秒。

这些连接条件非常糟糕。只要你有这些,你就会被糟糕的性能所困扰。重新设计并尝试将你的逻辑分割成更小的部分。我确实观察到我的本地机器有10倍的改进,但由于某种原因,当我在服务器上运行quey时,它会无限期地挂起(几分钟后我停止了它)我的开发机器是mysql 5.6,而服务器是5.5,但我怀疑这可能是问题所在。