我在mysql中为报告工具编写了以下查询。
这是一个内联选择。查询给出了正确的结果,但需要很长时间才能运行。有人可以建议任何替代方式或编写查询以使其更有效。
SELECT z.name1, (
SELECT COUNT( AES_DECRYPT( l.answertext, "aaa" ) )
FROM household_data l
INNER JOIN sms_household m
ON l.prim_key = m.hhid
INNER JOIN sms_psu n
ON n.psu = m.psu
AND n.state = m.state
AND n.district = m.district
INNER JOIN (
SELECT p.prim_key, p.fieldname
FROM household_data p
WHERE p.basicname = 'Q05'
AND AES_DECRYPT( p.answertext, "aaa" ) =2
) women
ON l.prim_key = women.prim_key
AND SUBSTR( l.fieldname, 5, 1 ) = SUBSTR( women.fieldname, 5, 1 )
WHERE l.basicname = 'Q08' AND AES_DECRYPT( l.answertext, "aaa" ) = 14
AND z.psu = n.psu
[AND n.state IN ( {state} )]
[AND n.district IN ( {district} )]
) female14, (
SELECT COUNT( AES_DECRYPT( l.answertext, "aaa" ) )
FROM household_data l
INNER JOIN sms_household m ON l.prim_key = m.hhid
INNER JOIN sms_psu n
ON n.psu = m.psu
AND n.state = m.state
AND n.district = m.district
INNER JOIN (
SELECT p.prim_key, p.fieldname
FROM household_data p
WHERE p.basicname = 'Q05'
AND AES_DECRYPT( p.answertext, "aaa" ) =2
) women
ON l.prim_key = women.prim_key
AND SUBSTR( l.fieldname, 5, 1 ) = SUBSTR( women.fieldname, 5, 1 )
WHERE l.basicname = 'Q08' AND AES_DECRYPT( l.answertext, "aaa" ) = 15
AND z.psu = n.psu
[AND n.state IN ( {state} )]
[AND n.district IN ( {district} )]
) female15, (
SELECT COUNT( AES_DECRYPT( l.answertext, "aaa" ) )
FROM household_data l
INNER JOIN sms_household m
ON l.prim_key = m.hhid
INNER JOIN sms_psu n
ON n.psu = m.psu
AND n.state = m.state
AND n.district = m.district
INNER JOIN (
SELECT p.prim_key, p.fieldname
FROM household_data p
WHERE p.basicname = 'Q05'
AND AES_DECRYPT( p.answertext, "aaa" ) =2
) women
ON l.prim_key = women.prim_key
AND SUBSTR( l.fieldname, 5, 1 ) = SUBSTR( women.fieldname, 5, 1 )
WHERE l.basicname = 'Q08' AND AES_DECRYPT( l.answertext, "aaa" ) =16
AND z.psu = n.psu
[AND n.state IN ( {state} )]
[AND n.district IN ( {district} )]
) female16, (
SELECT count(AES_DECRYPT(household_data.answertext , "aaa")) * 100 / (
SELECT count(AES_DECRYPT(household_data.answertext , "aaa"))
FROM household_data
INNER JOIN sms_household
INNER JOIN sms_psu
ON sms_psu.psu = sms_household.psu
AND sms_psu.state = sms_household.state
AND sms_psu.district = sms_household.district
WHERE basicname = 'Q07_year' AND z.psu= sms_psu.psu
[AND sms_psu.state IN ( {state} )]
[AND sms_psu.district IN ( {district} )]
)
FROM household_data
INNER JOIN sms_household
INNER JOIN sms_psu
ON sms_psu.psu = sms_household.psu
AND sms_psu.state = sms_household.state
AND sms_psu.district = sms_household.district
WHERE AES_DECRYPT(household_data.answertext , "aaa") = 9998
AND basicname = 'Q07_year'
AND z.psu = sms_psu.psu
[AND sms_psu.state IN ( {state} )]
[AND sms_psu.district IN ( {district} )]
) PercYearDontKnow
FROM household_data x
INNER JOIN sms_household y
ON x.prim_key = y.hhid
INNER JOIN sms_psu z
ON y.psu = z.psu
AND z.state = y.state
AND z.district = y.district
WHERE 1=1
[AND y.state IN ( {state} )]
[AND y.district IN ( {district} )
GROUP BY z.psu
答案 0 :(得分:1)
我编辑了您的帖子,使您的查询结构更加清晰。我建议您在自己的代码中执行相同的操作。
重组后,很明显你正在重复一些查询以找到female14,female15和female16。
也许您应该为该部分单独查询,如下所示:
SELECT n.name1,
n.psu,
AES_DECRYPT( l.answertext, "aaa" ) AS answer,
COUNT(*) as count
FROM household_data l
INNER JOIN sms_household m
ON l.prim_key = m.hhid
INNER JOIN sms_psu n
ON n.psu = m.psu
AND n.state = m.state
AND n.district = m.district
INNER JOIN (
SELECT p.prim_key, p.fieldname
FROM household_data p
WHERE p.basicname = 'Q05'
AND AES_DECRYPT( p.answertext, "aaa" ) =2
) women
ON l.prim_key = women.prim_key
AND SUBSTR( l.fieldname, 5, 1 ) = SUBSTR( women.fieldname, 5, 1 )
WHERE l.basicname = 'Q08'
AND AES_DECRYPT( l.answertext, "aaa" ) = 14
[AND n.state IN ( {state} )]
[AND n.district IN ( {district} )]
GROUP BY n.psu, AES_DECRYPT( l.answertext, "aaa" )
该查询应该为您提供Q08答案及其编号的摘要。
然后,您可以为PercYearDontKnow创建单独的查询。我相信之后重新组装数据仍然会比frankenquery更快。或者,将上述查询编码为SQL视图,并将其组合到更大的查询中。
顺便说一下,您可以使用COUNT( AES_DECRYPT( l.answertext, "aaa" ) )
而不是COUNT(*)
。这意味着将更少地调用解密函数。
另一个选择是SELECT AES_ENCRYPT( "2", "aaa" )
并在比较Q08时将该值用作常量。这样,每个字段都不需要重复解密。
之后,我会按照另一个答案中给出的优化建议,特别是查看执行路径,看看是否需要添加索引。
答案 1 :(得分:0)
丑陋的......我的建议:
当然,在测试环境中做所有这些,而不是生产,它可能是凌乱的。 另一个建议,一次一步,检查每个小修改,以确保结果仍然相同。保存结果进行比较,最后获得好结果。