Mysql 加载查询花费了太多时间

Mysql 加载查询花费了太多时间,mysql,sql,Mysql,Sql,我需要从具有给定条件的sales表中选择数据,如果sales表中的vendor=affiliate,以及上面sql中的ss.orderid=sf=orderid,我也需要从salesaff表中选择数据 我在一些帮助下写了这篇文章,但这个查询需要195秒才能加载。sales表包含8000行,并按salests、供应商、附属公司、orderid进行索引。salesaff表包含6000行,并由orderid索引 两个表包含相同的列 一些事实: ->若我将自定义列从'yes'和'no'中分别删除为aff

我需要从具有给定条件的sales表中选择数据,如果sales表中的vendor=affiliate,以及上面sql中的ss.orderid=sf=orderid,我也需要从salesaff表中选择数据

我在一些帮助下写了这篇文章,但这个查询需要195秒才能加载。sales表包含8000行,并按salests、供应商、附属公司、orderid进行索引。salesaff表包含6000行,并由orderid索引

两个表包含相同的列

一些事实: ->若我将自定义列从'yes'和'no'中分别删除为aff和aff,那个么若我使用limit 100或其他什么,那个么将执行查询。否则加载需要195秒

若我使用limit100,那个么查询将在2秒内执行。但在没有限制的情况下,它给出了错误代码500。
此外,我还需要总价。有人能帮我吗?

第一个效率是子查询中的order by是不必要的,除非您在那里放置限制子句。所以试试这个:

 ( SELECT 'no' AS aff,
         ss.orderid, ss.secondaff, ss.saletype, ss.price,
         ss.affiliate, ss.vendor,
         ss.cpa,ss.rebill,ss.salests,ss.fname,ss.lname 
    FROM sales ss 
   WHERE 1=1
     AND ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') 
ORDER BY ss.salests DESC ) 
  UNION ALL 
 (   SELECT 'yes' AS aff, ss.orderid,ss.secondaff,ss.saletype,sf.price,
            ss.affiliate,ss.vendor,ss.cpa,ss.rebill,ss.salests,ss.fname,ss.lname 
       FROM salesaff sf 
      INNER JOIN sales ss ON ss.orderid=sf.orderid 
      WHERE 1=1 
        AND ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') 
   ORDER BY sf.salests DESC ) 
ORDER BY salests DESC

您可以通过遍历该表一次并对salesaff表进行左联接来完全简化。那么您的是/否状态的情况/时间

我会有一个关于供应商、协会、销售人员的索引

(SELECT 'no' AS aff, ss.orderid, ss.secondaff, ss.saletype, ss.price, ss.affiliate, 
         ss.vendor, ss. cpa, ss.rebill, ss.salests, ss.fname, ss.lname 
 FROM sales ss 
 WHERE 1=1 AND ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade')
) 
UNION ALL 
( SELECT 'yes' AS aff, ss.orderid, ss.secondaff, ss.saletype, sf.price, ss.affiliate, 
         ss.vendor, ss.cpa, ss.rebill, ss.salests, ss.fname, ss.lname 
 FROM salesaff sf INNER JOIN
      sales ss
      ON ss.orderid = sf.orderid 
 WHERE 1=1 AND ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') 
 ) 
ORDER BY salests DESC

嘿嘿。这很难。您可能得到了正确的结果,但您的主机提供商正在超时您的查询,因此您无法判断。我觉得这两张桌子不大

首先,如果可以的话,增加超时时间,特别是对于调试。如果低效的查询没有完成,就很难确保正确性。世界上最有效的查询如果是错误的,就毫无价值。请向您的主机提供商支持人员寻求帮助

其次,如果查询完成并返回结果集的第一行所需的时间太长,您将获得超时。如果您的主机语言在使用整个resultset时速度较慢,您也可能会得到一个超时,因此请确保您这样做是有效的

第三,让我们把它分解。您正在查找一组特定的销售记录。你在做手术。这很可能保证了完整的表扫描,这对性能不太好

您还可以跳过WHERE子句中的1=1。这通常是为了让宿主语言的代码构造变得更简单。这不应该影响性能,但也无济于事

做一些猜测:假设ss.orderid是唯一的自动递增主键字段,您可以尝试在上添加复合索引(覆盖索引)

SELECT 
      CASE when sf.orderid is null 
           then 'no' else 'yes' end AS aff,
      ss.orderid, 
      ss.secondaff, 
      ss.saletype, 
      ss.price,
      ss.affiliate, 
      ss.vendor,
      ss.cpa,
      ss.rebill,
      ss.salests,
      ss.fname,
      ss.lname 
   FROM 
      sales ss
         LEFT JOIN salesaff sf 
            ON ss.orderid=sf.orderid 
   WHERE
         ss.vendor = '3kpertrade' 
      OR ss.affiliate = '3kpertrade'
   ORDER BY 
      ss.salests DESC

然后使用以下查询检索需要查找的orderid值列表

   (affiliate,orderid) 
此子查询有效地查找所需的orderid值集。我建议的两个覆盖指数将显著提高性能。不要在这里全部使用UNION,请使用UNION,否则可能会得到一些重复的数据

然后,您可以使用此查询来获取一些订单数据,即UNIONALL的第一部分

我建议你用这么多的查询来调试你的应用程序。确保它显示的内容正确

您似乎在查询中实现了影子预订系统。也就是说,当一个特定的订单出现在salesaff表中时,您将在这个查询的结果集中复制它。看起来您从salesaff检索到的唯一信息是价格。对吗?联盟销售是否在您的联盟所有结果集中出现多次

同样,查询的后半部分如下所示:

SELECT 'no' AS aff,
       ss.orderid, ss.secondaff, ss.saletype, ss.price,
       ss.affiliate, ss.vendor,
       ss.cpa,ss.rebill,ss.salests,ss.fname,ss.lname 
  FROM sales ss 
  JOIN (
         SELECT orderid FROM sales WHERE vendor = '3kpertrade'
          UNION
         SELECT orderid FROM sales WHERE affiliate = '3kpertrade'
       ) ids ON ss.orderid = ids.orderid 
如果你从salesaff得到的唯一信息实际上是价格,那么一个覆盖指数

SELECT 'yes' AS aff, ss.orderid, ss.secondaff, ss.saletype,
        sf.price,
        ss.affiliate, ss.vendor, ss.cpa, ss.rebill, ss.salests, ss.fname, ss.lname 
  FROM sales AS ss 
  JOIN (
         SELECT orderid FROM sales WHERE vendor = '3kpertrade'
          UNION
         SELECT orderid FROM sales WHERE affiliate = '3kpertrade'
       ) ids ON ss.orderid = ids.orderid 
  JOIN salesaff sf ON ss.orderid=sf.orderid 
这将对查询有所帮助

最后,按顺序完成所有的联合


观察。如果sales.salests是一个时间戳,如果sales.orderid是一个自动递增索引,并且如果您从不更新sales.salests而只插入它,然后按orderid DESC下单与按salests DESC下单做相同的事情。这可能会节省一点时间。

您在开始时是否缺少开头括号?我确信这是一个拼写错误,并且不能解决问题BTW,因为您自己的理解和对我们在StackOverflow上的礼貌,请考虑编辑SQL查询,这样断线有助于显示Logic。抱歉,这是一个打印错误。哦,不,我也编辑了你的。很抱歉也许有个虫子在里面。发生了一些奇怪的事情。处理请求时出错错误代码:500错误文本:内部服务器错误。一模一样。如果我使用限制100,则数据将在2秒内显示。@user3144629。尝试直接在数据库上运行查询。是的,我直接从phpmyadmin运行。若我添加限制100,那个么执行查询需要2秒。没有限制,我得到的错误超过500个错误代码。@user3144629。在没有最终订单的情况下,是否会出现相同的错误。我对这个问题的解释是OP需要所有的销售,然后是附属公司。orderid不能为null。这两个表具有相同的列,但当vendor=affiliate时,应选择salesaff
在销售方面。我需要跟踪从中检索表的行,因此请选择“否”/“是”作为aff。我认为我们根本无法通过左/右连接来处理。是的,没错。这个查询是不够的,因为它只从一个表中选择。我喜欢你的答案和回答方式。最后,我在你的回复中做了一些修改。我加入了同一个表sales的数据,并仅从salesaff检索到price。它现在正在工作。非常感谢您的支持。我喜欢它。
SELECT 'no' AS aff,
       ss.orderid, ss.secondaff, ss.saletype, ss.price,
       ss.affiliate, ss.vendor,
       ss.cpa,ss.rebill,ss.salests,ss.fname,ss.lname 
  FROM sales ss 
  JOIN (
         SELECT orderid FROM sales WHERE vendor = '3kpertrade'
          UNION
         SELECT orderid FROM sales WHERE affiliate = '3kpertrade'
       ) ids ON ss.orderid = ids.orderid 
SELECT 'yes' AS aff, ss.orderid, ss.secondaff, ss.saletype,
        sf.price,
        ss.affiliate, ss.vendor, ss.cpa, ss.rebill, ss.salests, ss.fname, ss.lname 
  FROM sales AS ss 
  JOIN (
         SELECT orderid FROM sales WHERE vendor = '3kpertrade'
          UNION
         SELECT orderid FROM sales WHERE affiliate = '3kpertrade'
       ) ids ON ss.orderid = ids.orderid 
  JOIN salesaff sf ON ss.orderid=sf.orderid 
 (orderid, price)