我有一个包含 8100 万条记录的数据库表,这些记录用于将特定 URL 与请求生成 url 的客户联系起来。为了从这个表中查询 url 有点合理,我将 url 字段设置为 a varchar(500)
(我们看到的最大 url 长度是 410)。
当我在 SSMS 中运行以下查询时,我会立即得到结果:
select CustomerId, UserId, Requested from LogURL where LogData = '<url>'
然后我在 C# 中编写了一个方法来为我处理日志文件执行此查询:
public UrlInformation GetInfoForUrl(string url)
{
const string query = "select top 1 CustomerId, UserId, Requested from LogURL where LogData = @url";
using (var command = new SqlCommand(query, _connection))
{
command.Parameters.Add(new SqlParameter
{
DbType = DbType.AnsiString,
ParameterName = "url",
Value = url
});
using (var reader = command.ExecuteReader())
{
UrlInformation info = null;
// Sometimes there are multiple results, just take the first
if (reader.Read())
{
var customerId = reader.GetInt32(0);
var userId = reader.GetInt32(1);
var date = reader.GetDateTime(2);
info = new UrlInformation
{
CustomerId = customerId,
UserId = userId,
RequestedDate = date
};
}
return info;
}
}
(注意这个类在构造函数中创建并打开sql连接,并在Dispose()中dispose,所以应该重用同一个连接)。
当此代码运行时,command.ExecuteReader()
每个需要 3-5 秒(通过StopWatch
类测量)。打开 sql 探查器,我看到正在执行的实际查询是:
exec sp_executesql N'select top 1 CustomerId, UserId, Requested from LogURL where LogData = @url',N'@url nvarchar(346)',@url=N'<url>'
由于它将 url 转换为 anvarchar
它没有使用我的varchar()
引用,并且似乎在进行全表扫描。
如何让 C# 代码将 url 视为 varchar 而不是 nvarchar?