( 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
我需要从具有给定条件的sales表中选择数据,如果vendor = affiliate在sales表中,并且ss.orderid = sf = orderid,则需要从salesaff
表中选择数据。
我写了一些帮助,但查询花了195秒加载。 sales table
包含8000行和销售商,供应商,附属机构,orderid索引。 salesaff
表包含6000行,并由orderid索引
两个表都包含相同的列。
一些事实: - >如果我从两者中删除自定义列('yes'作为aff,'no'作为aff),那么如果我使用limit 100或者其他东西,则执行查询。否则加载需要195秒。
如果我使用限制100,则在2秒内执行查询。但是没有限制,它给出了错误代码500。 而且,我也需要总价。有人能帮助我吗?
答案 0 :(得分:1)
第一个效率是子查询中的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')
)
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
答案 1 :(得分:1)
首先,如果可以,请增加超时时间,尤其是调试时。如果你的低效查询没有完成,很难确保正确性。如果它错了,那么世界上最有效的查询就毫无价值。请向您的托管服务提供商支持人员寻求帮助。
其次,如果查询完成并返回结果集的第一行需要很长时间,您将获得超时。如果您的宿主语言使用整个结果集的速度很慢,您也可能会超时,因此请确保您有效地执行此操作。
第三,让我们把它分解。您正在查找特定的销售记录集。你正在进行OR操作。最有可能保证全表扫描,这对性能不太好。
您也可以跳过1=1
条款中的WHERE
。这通常被放在那里作为一个hack,使宿主语言的代码构造更简单一些。它不应该损害性能,但它无济于事。
进行一些猜测:假设ss.orderid
是唯一(自动增量)主键字段,您可以尝试添加复合索引 - 覆盖索引 -
(vendor, orderid)
和
(affiliate,orderid)
然后使用以下查询来检索您需要查找的orderid值列表。
SELECT orderid FROM sales WHERE vendor = '3kpertrade'
UNION
SELECT orderid FROM sales WHERE affiliate = '3kpertrade'
此子查询有效地查找您需要的orderid
值集。我建议的两个覆盖索引将显着提高性能。 (请勿在此处使用UNION ALL
,使用UNION
,否则您可能会获得一些重复数据。)
然后,您可以使用此查询获取部分订单数据 - UNION ALL
的第一部分。
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
表格中出现特定订单时,您在此查询的结果集中重复它。看起来您从salesaff
检索的唯一信息就是价格。那是对的吗?会员销售是否会在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 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
如果您从salesaff
提取的唯一信息实际上是价格,那么覆盖索引
(orderid, price)
将有助于此查询。
最后,执行UNION ALL和ORDER BY
。
观察。如果sales.salests
是时间戳,并且sales.orderid
是自动递增索引,并且您永远不会更新sales.salests
但只插入它,那么ORDER BY orderid DESC
将执行相同的操作为ORDER BY salests DESC
。这可能会节省一点时间。
答案 2 :(得分:0)
您可以通过一次遍历表并对salesaff表进行左连接来完全简化。然后情况/何时为您的是/否状态
我会有一个索引(供应商,aaffiliate,salests)
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