SQL数据量才32W条,查询就已经达到将近10S,请问如何优化?

qq_33646435 2018-08-08 10:42:42
1、分页查询(每次查询10条数据,平均耗时6S)
SELECT *
FROM (
SELECT i.id, i.Url, i.ServicePath, p.ProductName, s.Name AS sName
, p.Brand, p.ASIN, p.Country, p.Price
, (ROW_NUMBER() OVER (ORDER BY i.Id) - 1) / 10 AS pagenum
FROM Product_Images i
LEFT JOIN Product p ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
) t
WHERE pagenum = 1 - 1

2、查询全部(32.4W条数据,耗时23S)
select i.id, i.Url, i.ServicePath, p.ProductName, s.Name AS sName
, p.Brand, p.ASIN, p.Country, p.Price FROM Product_Images i
LEFT JOIN Product p ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s ON p.StoreGuid = s.StoreGuid

3、索引使用情况

...全文
277 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
吉普赛的歌 2018-08-08
  • 打赏
  • 举报
回复
SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
ORDER BY i.id
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY;

这条需要几秒?
qq_33646435 2018-08-08
  • 打赏
  • 举报
回复
引用 4 楼 yenange 的回复:
--删除无用的索引。因为主键本身也是索引,没必要再建立
DROP INDEX IX_Product_Images ON Product_Images
DROP INDEX IX_Product ON Product

--连接字段增加索引
CREATE INDEX IX_Product_Images_ProductGuid ON Product_Images(ProductGuid);
CREATE INDEX IX_Product_ProductGuid ON Product(ProductGuid);
CREATE INDEX IX_Product_StoreGuid ON Product(StoreGuid);
CREATE INDEX IX_Store_StoreGuid ON Store(StoreGuid);


做完这些, 再看分页是否快了?

尴尬了,还是跟以前速度一样的
吉普赛的歌 2018-08-08
  • 打赏
  • 举报
回复
--删除无用的索引。因为主键本身也是索引,没必要再建立
DROP INDEX IX_Product_Images ON Product_Images
DROP INDEX IX_Product ON Product

--连接字段增加索引
CREATE INDEX IX_Product_Images_ProductGuid ON Product_Images(ProductGuid);
CREATE INDEX IX_Product_ProductGuid ON Product(ProductGuid);
CREATE INDEX IX_Product_StoreGuid ON Product(StoreGuid);
CREATE INDEX IX_Store_StoreGuid ON Store(StoreGuid);


做完这些, 再看分页是否快了?
qq_33646435 2018-08-08
  • 打赏
  • 举报
回复
引用 2 楼 yenange 的回复:
1. 贴出下面脚本的执行结果的截图。
EXEC sp_spaceused 'Product_Images'
EXEC sp_spaceused 'Product'
EXEC sp_spaceused 'Store'
EXEC sp_helpindex 'Product_Images'
EXEC sp_helpindex 'Product'
EXEC sp_helpindex 'Store'


2. 贴一下你分页的执行计划的截图.


吉普赛的歌 2018-08-08
  • 打赏
  • 举报
回复
1. 贴出下面脚本的执行结果的截图。
EXEC sp_spaceused 'Product_Images'
EXEC sp_spaceused 'Product'
EXEC sp_spaceused 'Store'
EXEC sp_helpindex 'Product_Images'
EXEC sp_helpindex 'Product'
EXEC sp_helpindex 'Store'


2. 贴一下你分页的执行计划的截图.
丰云 2018-08-08
  • 打赏
  • 举报
回复
分页?????

分页在那里??????
qq_33646435 2018-08-08
  • 打赏
  • 举报
回复
引用 12 楼 yenange 的回复:
[quote=引用 11 楼 qq_33646435 的回复:]
[quote=引用 10 楼 yenange 的回复:]
DECLARE @pageIndex INT,@pageSize INT
SET @pageIndex=1
SET @pageSize=10

SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
ORDER BY i.id
OFFSET (@pageIndex-1)*@pageSize ROWS
FETCH NEXT @pageSize ROWS ONLY;

很感谢你!!![/quote]
没事就结贴吧, [/quote]
结贴了!分数给你了,很感谢你!
吉普赛的歌 2018-08-08
  • 打赏
  • 举报
回复
引用 11 楼 qq_33646435 的回复:
[quote=引用 10 楼 yenange 的回复:]
DECLARE @pageIndex INT,@pageSize INT
SET @pageIndex=1
SET @pageSize=10

SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
ORDER BY i.id
OFFSET (@pageIndex-1)*@pageSize ROWS
FETCH NEXT @pageSize ROWS ONLY;

很感谢你!!![/quote]
没事就结贴吧,
qq_33646435 2018-08-08
  • 打赏
  • 举报
回复
引用 10 楼 yenange 的回复:
DECLARE @pageIndex INT,@pageSize INT
SET @pageIndex=1
SET @pageSize=10

SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
ORDER BY i.id
OFFSET (@pageIndex-1)*@pageSize ROWS
FETCH NEXT @pageSize ROWS ONLY;

很感谢你!!!
吉普赛的歌 2018-08-08
  • 打赏
  • 举报
回复
DECLARE @pageIndex INT,@pageSize INT
SET @pageIndex=1
SET @pageSize=10

SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
ORDER BY i.id
OFFSET (@pageIndex-1)*@pageSize ROWS
FETCH NEXT @pageSize ROWS ONLY;
qq_33646435 2018-08-08
  • 打赏
  • 举报
回复
引用 8 楼 yenange 的回复:
[quote=引用 7 楼 qq_33646435 的回复:]
[quote=引用 6 楼 yenange 的回复:]
SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
ORDER BY i.id
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY;

这条需要几秒?
这条不需要时间,很快执行。0秒[/quote]
这种是新式的分页, 就按这种来吧。

row_number 分页按道理也不慢, 你再试下这种看看:
SELECT * FROM (
SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price,
ROW_NUMBER() OVER (ORDER BY id) AS rid
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
) AS t
WHERE t.rid>0 AND t.rid<=10
[/quote]
恩,谢谢你第二张也快,0S查询出来数据。但是想请教你个问题:
第一种你说的新式分页,怎么定义第几页呢?(FETCH NEXT 10 ROWS ONLY 是查询10条数)
假如我每页显示10条 想显示第三页(21~30条)的数据,要怎么修改?
吉普赛的歌 2018-08-08
  • 打赏
  • 举报
回复
引用 7 楼 qq_33646435 的回复:
[quote=引用 6 楼 yenange 的回复:]
SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
ORDER BY i.id
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY;

这条需要几秒?
这条不需要时间,很快执行。0秒[/quote]
这种是新式的分页, 就按这种来吧。

row_number 分页按道理也不慢, 你再试下这种看看:
SELECT * FROM (
SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price,
ROW_NUMBER() OVER (ORDER BY id) AS rid
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
) AS t
WHERE t.rid>0 AND t.rid<=10
qq_33646435 2018-08-08
  • 打赏
  • 举报
回复
引用 6 楼 yenange 的回复:
SELECT i.id,
i.Url,
i.ServicePath,
p.ProductName,
s.Name AS sName,
p.Brand,
p.ASIN,
p.Country,
p.Price
FROM Product_Images i
LEFT JOIN Product p
ON i.ProductGuid = p.ProductGuid
LEFT JOIN Store s
ON p.StoreGuid = s.StoreGuid
WHERE 1 = 1
ORDER BY i.id
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY;

这条需要几秒?
这条不需要时间,很快执行。0秒

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧