sql - 使用参数更快地进行 T-Sql 查询
问题描述
首先我想说我真的是数据库初学者,不要评判我。
我从 web 服务接收到很多参数,我必须使用这些参数进行 sql 查询。问题是我的查询消耗了大量的 cpu,因为我对查询的优化不好。
SELECT
SUM(t.total_amount) as SumaAmount,
COUNT(t.id) as TotalTransaccions
FROM RealTimeVending.dbo.rtv_turnover_transaction as t,
RealTimeVending.dbo.rtv_trans_articles as ta,
RealTimeVending.dbo.articles as art, RealTimeVending.dbo.groups,
RealTimeVending.dbo.Clients as s,
RealTimeVending.dbo.rtv_transactions as tr,
RealTimeVending.dbo.tills as till, RealTimeVending.dbo.Ubicacion as u,
RealTimeVending.dbo.Operadores as o
where t.operador_id=o.ID and t.transaction_id=ta.transaction_id and
art.id=ta.article_id and s.id=t.cliente_id and tr.id=t.transaction_id
and groups.id=art.group_a_id and t.ubicacio_id=u.id
and convert(date,t.trans_date) >='"+globalMap.get("datainici")+"'and
convert(date,t.trans_date) <= '"+globalMap.get("datafinal")+"'and
and (s.codigo IS NULL or s.codigo like '%"+globalMap.get("client")+"%')
and (t.total_amount IS NULL or t.total_amount like'"+globalMap.get("amount")+"%')
想象一下,我将 web 服务中的所有参数都为空。数据库将花费大量时间处理这些参数。我想做的是一个查询,我可以在其中搜索不为空的参数。例如,如果“t.total_amount”为空,我不想在查询中插入搜索。
我希望你能理解我的问题。太感谢了。
解决方案
这是使用现代JOIN
语法快速重写您的查询:
SELECT
SUM(t.total_amount) AS SumaAmount,
COUNT(t.id) AS TotalTransaccions
FROM
RealTimeVending.dbo.rtv_turnover_transaction t
INNER JOIN RealTimeVending.dbo.rtv_trans_articles ta ON ta.transaction_id = t.transaction_id
INNER JOIN RealTimeVending.dbo.articles art ON art.id = ta.article_id
INNER JOIN RealTimeVending.dbo.groups g ON g.id = art.group_id
INNER JOIN RealTimeVending.dbo.Clients s ON s.id = t.cliente_id
INNER JOIN RealTimeVending].dbo.rtv_transactions tr ON tr.id = t.transaction_id
--INNER JOIN RealTimeVending.dbo.tills till (not used)
INNER JOIN RealTimeVending.dbo.Ubicacion u ON u.id = t.ubicacio_id
INNER JOIN RealTimeVending.dbo.Operadores o ON o.id = t.operador_id
WHERE
CONVERT(DATE, t.trans_date) >= '"+globalMap.get("datainici")+"' --is this really not already a date?
AND CONVERT(DATE, t.trans_date) <= '"+globalMap.get("datafinal")+"'
AND (s.codigo IS NULL or s.codigo LIKE '%"+globalMap.get("client")+"%')
AND (t.total_amount IS NULL or t.total_amount LIKE '"+globalMap.get("amount")+"%');
让我印象深刻的第一件事是您trans_date
正在转换为 aDATE
进行比较,这可能效率低下。更好的是,如果您可以将此标准更改为类似的内容t.trans_date BETWEEN <dateinici> AND <datefinal>
,因为这样就可以使用索引。
您确实应该正确使用参数,因为这有助于避免 SQL 注入。
根据优化器的不同,它应该意识到比较一个值是没有意义的,如果它是NULL
并且你有一个约束x IS NULL OR x LIKE <something>
。
可能值得进行示例查询并查看它使用的执行计划?
使用现代JOIN
语法,很明显你的tills
表没有被使用,所以本质上是 a CROSS JOIN
,如果它是一个大表,它会减慢一切吗?
推荐阅读
- javascript - 使用 API 从客户端保存图像
- sublimetext3 - 自动换行时如何自动换行
- php - laravel 中的同步功能无法按预期工作
- angular - 将 @Input 限制为 Angular 中的预定义值列表
- python - Python 抛出一个 MemoryError,当我安装的 RAM 量无论如何应该能够容纳我提供给列表变量的内容时
- google-sheets - 根据复选框过滤工作簿中的所有工作表(在 Google 表格中)
- mongodb - Mongoose 总结具有相同别名的子文档数组元素
- android-studio - 使用 Geofire 不显示标记
- html - 使 div 与背景图像一样高
- c - 使用静态存储类时,堆栈是否用于函数实现?如果是,它是如何工作的?如果没有,使用什么?