如何优化访问计数器 SQL 查询?

Posted

技术标签:

【中文标题】如何优化访问计数器 SQL 查询?【英文标题】:How to optimize visit counter SQL query? 【发布时间】:2021-02-03 15:34:52 【问题描述】:

使用 SQL Server 2016,我创建了表 VISIT,其中包含 3 列 IDsettodaycounter。这是我用来计算每日访问次数的 asp 代码。目前该表有2000多条记录:

<%
'today is calculated on local calendar then:

sql="select * from visit where settoday='"& today &"'"
recordSet.open sql,objcon
if not recordSet.eof then

    sql="update visit set counter=counter+1 where id=" & recordSet("id")
    objcon.execute sql

else
    
    sql="insert into visit (settoday,counter) values ('" & today & "','1')"
    objcon.execute sql

end if
recordSet.close
%>

ID 列是主键,我还在 settoday 列上创建了一个索引。但是当我检查事件探查器时,更新查询需要很长时间才能执行。我还能做些什么来优化更新代码?

【问题讨论】:

警告,您的代码容易受到注入攻击。 参数化您的查询。 你的表有索引还是主键 是的,我提到过 ID 是主键,settoday 是索引。 @查理脸 请通过pastetheplan.com分享这些查询的查询计划 为什么需要settoday 列上的索引?这会减慢表上的任何更新 【参考方案1】:

我认为避免两次访问数据库可以获得很多好处。 此外,您应该始终尝试使用占位符和参数,而不是连接值等。我认为这不是什么大问题,因为我认为 today 不是用户提供的值,但仍然。

2000 条记录根本不算多,但可以,在settoday 上建立索引 有所帮助,尤其是随着表的增长。如果您当前的版本很慢,那么我怀疑网络开销比查询的实际执行更应受到指责。

而不是首先获取todayID,然后在asp 中决定是否需要INSERTUPDATE,您可以在SQL 中的1 个单一操作中完成此操作。 自从我编写这种代码以来已经有很多年了,我不得不在记事本中写下来,所以你可能不得不在这里和那里修复一些东西,但我认为这是一个开始:

<%
sql = "DECLARE @today datetime = ?

UPDATE counter
   SET counter = counter + 1
 WHERE settoday = @today
 
 IF @@ROWCOUNT = 0
    BEGIN
        INSERT INTO visit (settoday, counter) values (@today, 1)"
    END"
    

set command = server.createobject("ADODB.Command")
set command.ActiveConnection = ...
command.QueryText = sql
command.CommandType = adCmdText
command.Parameters.Append(command.CreateParameter("@p1", adDate, adParamInput, today))
command.Execute

%>

【讨论】:

以上是关于如何优化访问计数器 SQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章

优化 sql 计数查询

如何组合 2 个 SQL 查询并检索累积计数?

SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句

用于计数和显示(列中的不同值)的 Sql 查询优化,按其他两列分组

如何在选择查询中增加 sql 计数器

SQL Server:计数请求优化