База данных состоит из одной таблицы (
Код: Выделить всё
ProductsКод: Выделить всё
CREATE TABLE [dbo].[Products]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[ProductName] [nvarchar](500) NOT NULL,
[Brand] [nvarchar](100) NOT NULL,
[Field1] [nvarchar](50) NULL,
[Field2] [nvarchar](50) NULL,
[Field3] [nvarchar](50) NULL,
[Field4] [nvarchar](50) NULL,
[Field5] [nvarchar](50) NULL,
Ix_Brands index(Brand),
CONSTRAINT [PK_Products]
PRIMARY KEY CLUSTERED ([ID] ASC)
)
Код: Выделить всё
using System;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
namespace SpeedTest
{
internal class Program
{
static void Main(string[] args)
{
var connectionString = "data source=.";
string[] Brands = new string[] { "Tesco", "Asda", "Boots", "Morrisons", "Amazon", "Ebay" };
var rnd = new Random();
DateTime startTime;
using (var con = new SqlConnection(connectionString))
{
var cmd = new SqlCommand("delete from products", con);
con.Open();
cmd.ExecuteNonQuery();
Console.WriteLine("Creating 100,000 products");
for (int i = 0; i < 100000; i++)
{
var brand = Brands[rnd.Next(Brands.Length)];
cmd.CommandText = $"insert into products(productName, brand, field1, field2, field3, field4, field5) values ('{brand}_{Guid.NewGuid()}', '{brand}', '{Guid.NewGuid()}', '{Guid.NewGuid()}', '{Guid.NewGuid()}', '{Guid.NewGuid()}', '{Guid.NewGuid()}')";
cmd.ExecuteNonQuery();
}
Console.WriteLine("Getting products by brand via ADO and product name prefix");
startTime = DateTime.Now;
foreach (var brand in Brands)
{
cmd.CommandText = $"select * from products where productName like '{brand}_%'";
var da = new SqlDataAdapter(cmd);
var dt = new DataTable();
da.Fill(dt);
}
Console.WriteLine($"Time taken: {(DateTime.Now - startTime).TotalMilliseconds}ms");
Console.WriteLine("Getting products by brand via ADO and indexed brand column");
startTime = DateTime.Now;
foreach (var brand in Brands)
{
cmd.CommandText = $"select * from products where brand='{brand}'";
var da = new SqlDataAdapter(cmd);
var dt = new DataTable();
da.Fill(dt);
}
Console.WriteLine($"Time taken: {(DateTime.Now - startTime).TotalMilliseconds}ms");
con.Close();
}
var db = new SpeedTestEntities();
Console.WriteLine("Getting products by brand via entity framework and product name prefix");
startTime = DateTime.Now;
foreach (var brand in Brands)
{
var products = db.Products.Where(p => p.ProductName.StartsWith(brand + "_")).ToList();
}
Console.WriteLine($"Time taken: {(DateTime.Now - startTime).TotalMilliseconds}ms");
Console.WriteLine("Getting products by brand via entity framework and indexed brand column");
startTime = DateTime.Now;
foreach (var brand in Brands)
{
var products = db.Products.Where(p => p.Brand.Equals(brand, StringComparison.OrdinalIgnoreCase)).ToList();
}
Console.WriteLine($"Time taken: {(DateTime.Now - startTime).TotalMilliseconds}ms");
Console.ReadLine();
}
}
}
р>
Код: Выделить всё
Creating 100,000 products
Getting products by brand via ADO and product name prefix
Time taken: 558.9306ms
Getting products by brand via ADO and indexed brand column
Time taken: 642.5258ms
Getting products by brand via entity framework and product name prefix
Time taken: 3266.8438ms
Getting products by brand via entity framework and indexed brand column
Time taken: 204.932ms
Может ли кто-нибудь меня спасти и посмотреть, что здесь происходит?EDIT: оказывается, что оба запроса ADO выполняют сканирование индекса PK_Products. Оба плана выполнения одинаковы. Это меня удивило, и я думал, что добавление индексированного столбца, безусловно, будет быстрее, но, видимо, нет.
План выполнения
Подробнее здесь: https://stackoverflow.com/questions/785 ... comparison
Мобильная версия