这是我在MySQL数据库上运行的查询。查询占用了更多时间,因为我们在订单表中有更多的记录。请根据查询计划建议优化查询的提示。
的MySQL>解释SELECT DISTINCT dt.customer_id,dt.email,dt.title,dt.fname,dt.lname,DT。 work_phone,dt.mobile_phone,dt.home_phone,dt.blacklist_reason,DT。 域,dt.domain_group,dt.my_account_flag,dt.marketing_preference,DT。 城市,dt.address1,dt.address2,dt.state,DT。 country,dt.zip,dt.country_code FROM(SELECT cc.customer_id,cc.email,cc.title,cc.fname,cc.lname, cc.work_phone,cc.mobile_phone,cc.home_phone,cc.blacklist_reason, cc.domain,cc.domain_group,cc.my_account_flag,cc.marketing_preference, ca.city,ca.address1,ca.address2,ca.state, ca.country,ca.zip,ca.country_code,odd.order_date FROM customer cc INNER JOIN customer_address ca ON cc.customer_id = ca.customer_id left 外连接order_delivery_details奇数 cc.customer_id = odd.customer_id WHERE cc.lname ='XXXXXX'和
ca.address_purpose ='XXXX'和(cc.domain in('XXXXXX_IE')|| cc.domain_group in('XXXXX','YYYYYY'))order by odd.order_date desc)dt LIMIT 0,500;
SQL:
SELECT
DISTINCT dt.customer_id,
dt.email,
dt.title,
dt.fname,
dt.lname,
dt. work_phone,
dt.mobile_phone,
dt.home_phone,
dt.blacklist_reason,
dt. domain,
dt.domain_group,
dt.my_account_flag,
dt.marketing_preference,
dt. city,
dt.address1,
dt.address2,
dt.state,
dt. country,
dt.zip,
dt.country_code
FROM (
SELECT
cc.customer_id,
cc.email,
cc.title,
cc.fname,
cc.lname,
cc.work_phone,
cc.mobile_phone,
cc.home_phone,
cc.blacklist_reason,
cc.domain,
cc.domain_group,
cc.my_account_flag,
cc.marketing_preference,
ca.city,
ca.address1,
ca.address2,
ca.state,
ca.country,
ca.zip,
ca.country_code,
odd.order_date
FROM
customer cc
INNER JOIN customer_address ca ON cc.customer_id=ca.customer_id
left outer join order_delivery_details odd on cc.customer_id=odd.customer_id
WHERE cc.lname = 'XXXXXX'
and ca.address_purpose='XXXX'
and ( cc.domain in ( 'XXXXXX_IE' )
or cc.domain_group in ( 'XXXXX' , 'YYYYYY' )
)
order by odd.order_date desc
) dt
LIMIT 0,500;
感谢您的回复。我无法在子查询之外移动顺序,因为主查询不包含order_date列。
这是要求。我们应该根据搜索条件搜索客户,并根据客户的最新order_date订购客户。客户可以有多个订单,我们必须选择最新订单的order_date并对客户进行排序。
首先,我列出所有加入订单表的客户,并根据order_date订购所有记录。 一旦根据order_date对所有记录进行排序,如果客户有多个订单,则很可能会有同一客户的多次记录。
现在我在除了order_date之外应用了不同的东西,以便获得明确的客户详细信息。
谢谢, Chandu
答案 0 :(得分:0)
重写查询,使其符合您的描述:您希望查看客户最后订单所订购的客户地址列表。要获取每个地址的条目,您按地址分组。并且按最后订单日期降序排序,您可以通过max(order_date)desc。
订购SELECT
cc.customer_id,
cc.email,
cc.title,
cc.fname,
cc.lname,
cc.work_phone,
cc.mobile_phone,
cc.home_phone,
cc.blacklist_reason,
cc.domain,
cc.domain_group,
cc.my_account_flag,
cc.marketing_preference,
ca.city,
ca.address1,
ca.address2,
ca.state,
ca.country,
ca.zip,
ca.country_code
FROM customer cc
INNER JOIN customer_address ca ON cc.customer_id = ca.customer_id
LEFT OUTER JOIN order_delivery_details odd on cc.customer_id = odd.customer_id
WHERE cc.lname = 'XXXXXX'
AND ca.address_purpose='XXXX'
AND (cc.domain in ( 'XXXXXX_IE' ) OR cc.domain_group in ('XXXXX', 'YYYYYY'))
GROUP BY ca.id
order by max(odd.order_date) desc
LIMIT 0,500;
这应该更快,因为您只需告诉dbms 您想要查看的内容,并且dbms可以找到如何实现此目的的最佳方式。
答案 1 :(得分:0)
它在客户表上选择使用的索引看起来就像是lname字段,但这似乎并没有使结果缩小很多。认为你需要添加几个索引,一个覆盖lname和domain,另一个覆盖lname和domain_group。然后你可以有2个联合查询。
SELECT
DISTINCT dt.customer_id,
dt.email,
dt.title,
dt.fname,
dt.lname,
dt. work_phone,
dt.mobile_phone,
dt.home_phone,
dt.blacklist_reason,
dt. domain,
dt.domain_group,
dt.my_account_flag,
dt.marketing_preference,
dt. city,
dt.address1,
dt.address2,
dt.state,
dt. country,
dt.zip,
dt.country_code
FROM (
SELECT
cc.customer_id,
cc.email,
cc.title,
cc.fname,
cc.lname,
cc.work_phone,
cc.mobile_phone,
cc.home_phone,
cc.blacklist_reason,
cc.domain,
cc.domain_group,
cc.my_account_flag,
cc.marketing_preference,
ca.city,
ca.address1,
ca.address2,
ca.state,
ca.country,
ca.zip,
ca.country_code,
odd.order_date
FROM
customer cc
INNER JOIN customer_address ca ON cc.customer_id=ca.customer_id
LEFT OUTER JOIN order_delivery_details odd on cc.customer_id=odd.customer_id
WHERE cc.lname = 'XXXXXX'
AND ca.address_purpose='XXXX'
AND cc.domain_group in ( 'XXXXX' , 'YYYYYY' )
UNION
SELECT
cc.customer_id,
cc.email,
cc.title,
cc.fname,
cc.lname,
cc.work_phone,
cc.mobile_phone,
cc.home_phone,
cc.blacklist_reason,
cc.domain,
cc.domain_group,
cc.my_account_flag,
cc.marketing_preference,
ca.city,
ca.address1,
ca.address2,
ca.state,
ca.country,
ca.zip,
ca.country_code,
odd.order_date
FROM
customer cc
INNER JOIN customer_address ca ON cc.customer_id=ca.customer_id
LEFT OUTER JOIN order_delivery_details odd on cc.customer_id=odd.customer_id
WHERE cc.lname = 'XXXXXX'
AND ca.address_purpose='XXXX'
AND cc.domain in ( 'XXXXXX_IE' )
ORDER BY odd.order_date desc
) dt
LIMIT 0,500;
我不确定您的原始查询是否需要内部和外部查询。 MySQL将允许您对未返回的列进行排序。但是,看起来主要问题是索引,并且您无法通过从2个联合查询返回的列来对联合查询的结果进行排序。
答案 2 :(得分:0)
您是否尝试过这样的查询:
SELECT DISTINCT
cc.customer_id,
cc.email,
cc.title,
cc.fname,
cc.lname,
cc.work_phone,
cc.mobile_phone,
cc.home_phone,
cc.blacklist_reason,
cc.domain
cc.domain_group,
cc.my_account_flag,
cc.marketing_preference,
ca.city,
ca.address1,
ca.address2,
ca.state,
ca.country,
ca.zip,
ca.country_code,
FROM
customer cc
INNER JOIN customer_address ca ON cc.customer_id=ca.customer_id
left outer join order_delivery_details odd on cc.customer_id=odd.customer_id
WHERE
cc.lname = 'XXXXXX'
AND ca.address_purpose='XXXX'
AND ( cc.domain in ( 'XXXXXX_IE' ) OR cc.domain_group in ( 'XXXXX' , 'YYYYYY' ) )
ORDER BY odd.order_date DESC
LIMIT 0,500
您不需要子选择来获得您想要的东西。