SQL 优化
Posted
技术标签:
【中文标题】SQL 优化【英文标题】:SQL optimazation 【发布时间】:2018-06-07 08:33:11 【问题描述】:我正在开发一个数据库,其中当前存储了总共 788 个数据,并且随着时间的推移不断增加。
我的代码如下:
SELECT DISTINCT R.remarks, R.payerId, R.payername, R.payeraddress, R.collectorName, R.serialno, OOI.phone_no, CR.cr_no, F.application_no, R.series, R.txndate, R.amount, T.toda_name, B.brand_name, M.motor_no, M.chassis_no,
M.plate_no, F.date_issue, M.year_model, M.body_color, OOI.ice_person_name, OOI.ice_person_address, OOI.ice_person_contact_no, M.motor_id, F.franchise_id, LEFT(R.remarks, 4) AS franchise_no, SUBSTRING(R.remarks,
CHARINDEX('|', R.remarks) + 1, LEN(R.remarks)) AS motor_noremarks
FROM etracs_tayabas.dbo.Receipt AS R INNER JOIN
etracs_tayabas.dbo.ReceiptItem AS RI ON RI.parentid = R.objid INNER JOIN
etracs_tayabas.dbo.IncomeAccount AS IA ON IA.objid = RI.acctid LEFT OUTER JOIN
dbo.vfTA_tblMotor AS M ON M.motor_no = SUBSTRING(R.remarks, CHARINDEX('|', R.remarks) + 1, LEN(R.remarks)) LEFT OUTER JOIN
dbo.vfTA_tblOperatorOtherInfo AS OOI ON OOI.operator_id = R.payerId LEFT OUTER JOIN
dbo.vfTA_tblCertificateOfRegistration AS CR ON CR.motor_id = M.motor_id LEFT OUTER JOIN
dbo.vfTA_tblFranchise AS F ON F.or_id = R.objid LEFT OUTER JOIN
dbo.vfTA_tblTODA AS T ON T.toda_id = M.toda_id LEFT OUTER JOIN
dbo.vfTA_tblReconciledTaxpayer AS RT ON RT.payer_id = R.payerId LEFT OUTER JOIN
dbo.vfTA_tblBrand AS B ON B.brand_id = M.brand_id
WHERE (IA.objid = 'FTFA00000242') AND (F.franchise_id IS NULL) AND (R.voidId IS NULL) AND (R.remarks IS NOT NULL) AND (RT.rtp_id IS NULL)
每次我运行此代码时,加载所有值总是需要长达 10 分钟或更长时间。我试图用相同的代码创建一个 SQL 视图,但是当我运行它时,总是显示错误 Execution Timeout
。
我想知道:
-
视图和存储过程的最佳优化方法是什么?
鉴于数据有 788 个数据并且随着时间的推移而增加,我如何才能减少加载数据所需的时间?
如何防止SQL甚至程序中出现大量的执行超时?
一些帮助教授 的网站。
我现在正在尝试学习优化,因为我注意到当我进行查询时,加载通常需要很长时间,有时会产生错误'Execution Timeout'
我目前对此并不陌生。提前致谢。
【问题讨论】:
什么是“788数据”? “数据”不是一个单位。你是说行吗?如果有,在哪个表中? @HoneyBadger 此查询显示 788 行,需要 10 分钟,有时需要 15 分钟。 您使用的是哪个 dbms?添加表和索引定义。有什么解释计划吗? @a_horse_with_no_name 更新了标签。感谢指正 【参考方案1】:我认为对如此多的列使用 DISTINCT 会花费很多。您的查询真的有必要吗?
我也想知道下面的部分。
LEFT OUTER JOIN dbo.vfTA_tblMotor AS M ON M.motor_no = SUBSTRING(R.remarks, CHARINDEX('|', R.remarks) + 1, LEN(R.remarks))
这意味着没有办法使用 INDEX 来处理这种关系。如何在存储子字符串结果的表 etracs_tayabas.dbo.Receipt 中添加一列,并在向表中插入/更新记录时计算它。这样,你可以为这个关系做INDEX,并可以优化JOIN的那部分。
【讨论】:
是的。因为代码从数据库中返回了很多重复的行。 如果您可以识别哪些列有重复项,那么您可以对这些特定列使用“分组依据”。它会让这个过程更快。 但正如我在查询中的 JOIN 中看到的那样,除了我在上面指出的 JOIN 之外,它们似乎都在使用某种 ID。如果这些是每个表中的主键,那么为什么会出现重复项是没有意义的。你为什么不首先澄清哪个表/连接导致这样的重复数据? 如果你得到重复,那么你的加入条件可能不正确。如果您的连接不正确,修复它们意味着您可以删除distinct
,并且您可能会获得良好的性能提升
@Nick.McDermaid 然后我将首先查看并检查我上面的代码。谢谢以上是关于SQL 优化的主要内容,如果未能解决你的问题,请参考以下文章