我有一个查询如下:
SELECT @tenor_from =CONVERT(DATETIME,MIN(spc.maturity_date),103)
FROM source_price_curve spc
INNER JOIN #source_price_curve_list spcl
ON spc.source_curve_def_id = spcl.price_curve_id
WHERE spc.as_of_date >= @as_of_date_from
Run Code Online (Sandbox Code Playgroud)
运行需要将近 12 秒。从连接中删除临时表 #source_price_curve_list 会在不到 1 秒的时间内给出结果。
该source_price_curve表有 1.3 亿条记录。临时表#source_price_curve_list在输出中有一条记录(如下所示)。将来可能会包含更多数据
select * from #source_price_curve_list
rowID price_curve_id
1 1
Run Code Online (Sandbox Code Playgroud)
为什么与单记录临时表的内部连接会使查询花费更长的时间?我需要将查询运行时间减少到 1 秒以内。
以下链接提供了带有连接的查询的执行计划:
https://www.brentozar.com/pastetheplan/?id=BksaaWjSb
没有join to temp table的查询运行不到1秒,执行计划链接如下:
https://www.brentozar.com/pastetheplan/?id=BJ2_3boSZ
表 source_price_curve 创建如下:
CREATE TABLE [dbo].[source_price_curve](
[source_curve_def_id] [int] NOT NULL,
[as_of_date] [datetime] NOT NULL,
[Assessment_curve_type_value_id] [int] NOT NULL,
[curve_source_value_id] [int] NOT NULL,
[maturity_date] [datetime] NOT NULL,
[curve_value] [float] NOT …Run Code Online (Sandbox Code Playgroud) 我编写了一个小程序来从文件导入产品详细信息更新,这比预期的要长得多。(为简洁起见,我将使用精简的示例。)
该程序执行以下操作:
COPYs 修改后的数据到临时表中。这一切都很好,除了UPDATE查询需要约 20 秒的时间来处理约 2000 行的小文件。
临时表如下所示:
CREATE TEMPORARY TABLE tmp_products (
product_id integer,
detail text
);
Run Code Online (Sandbox Code Playgroud)
我的更新查询非常简单:
UPDATE products
SET detail = t.detail
FROM tmp_products t
WHERE t.product_id = products.product_id
Run Code Online (Sandbox Code Playgroud)
为了加快速度,我尝试了以下方法,但收效甚微:
在临时表上创建 BTREE 索引。
CREATE INDEX tmp_products_idx
ON tmp_products
USING BTREE
(product_id);
Run Code Online (Sandbox Code Playgroud)
创建哈希索引:
CREATE INDEX tmp_products_idx
ON tmp_products
USING HASH
(product_id);
Run Code Online (Sandbox Code Playgroud)
这两个索引都没有显着改善更新时间。然后我想也许对表进行聚类会有所帮助,但这意味着我不能使用 HASH 索引。所以我修改了程序中的查询以使用 BTREE 索引,然后使用 CLUSTER/ANALYZE:
CREATE INDEX tmp_products_idx
ON tmp_products
USING BTREE
(product_id);
-- Program inserts data …Run Code Online (Sandbox Code Playgroud) 所以,我运行了 BrentOzar 脚本,它为同一查询确定了 10195 个计划!!!查询如下:
SELECT *
FROM [table1]
INNER JOIN [table2]
ON [table1].[versionId] = [table2].[VersionId]
INNER JOIN [table3]
ON [table2].[ContentId] = [table3].[nodeId]
INNER JOIN [table4]
ON [table3].[nodeId] = [table4].[id]
WHERE ([table4].[nodeObjectType] = 'abcde123-fgh3-4ijk-8lmn-424f222332ff')
AND ([table1].[published] = 0
AND [table1].[releaseDate] <= '2017-07-22 17:43:47')
AND ([table1].[newest]=1)
ORDER BY [table2].[VersionDate] DESC, [table4].[sortOrder]
Run Code Online (Sandbox Code Playgroud)
所有 10195 个之间的唯一区别是日期字段(发布日期)。每个计划具有不同日期的值。
关于索引,以下适用:
我已经阅读了关于索引的隐式转换影响性能的内容,因此在以下查询中
select count(*)
from fpc
where SKey in (201701, 201702)
Run Code Online (Sandbox Code Playgroud)
因为 SKey 是 int 类型,如果我将上面的查询更改为
select count(*)
from fpc
where SKey in ('201701', '201702')
Run Code Online (Sandbox Code Playgroud)
性能会下降。
我在一个表(有数百万行)上测试了这个。问题是为什么我没有看到执行计划和时间上的任何差异。
我在 SKey 上有非聚集列存储索引。
每个 SKey 大约有 2000 万行,我有大约 100 个不同的 SKey
我有一个跨两个大表的查询。第一个记录了一个位置的最新用户活动,第二个是一个带有位置自然主键的维度表。
这里的表大小大约为 1 亿行 inuser_location_rating和 1000 万行 in dim_location. 大多数用户有 < 1000 条记录user_location_rating,对于这些用户来说,查询性能已经足够了。
对于有大量活动数据的用户,这个查询,即使是两个简单的选择,仍然会很慢。我想提高查询性能。这可以通过添加额外的索引来完成吗?作为替代方案,有没有一种方法可以利用索引使有限的查询(如下)比完整查询更有效?
SELECT d.create_time
FROM user_location_rating f
JOIN dim_location d using(location_id)
WHERE f.user_id=?
AND f.platform=?
AND d.category=?;
SELECT d.create_time
FROM user_location_rating f
JOIN dim_location d using(location_id)
WHERE f.user_id=?
AND f.platform=?
AND d.category=?
ORDER BY d.create_time DESC
LIMIT 1000;
Run Code Online (Sandbox Code Playgroud)
EXPLAIN SELECT 对这些查询产生以下结果(例如,对于具有 999 个事件的用户)
+----+-------------+----------------------+--------+-------------------------------+-----------+---------+----------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | …Run Code Online (Sandbox Code Playgroud) 我无法获得将常规表连接到分区视图以消除不符合分区列谓词的表的查询。特别是,我对我对分区视图进行 LEFT OUTER JOIN 并且我的谓词涵盖一系列值的情况感兴趣。当我修改查询以使用 INNER JOIN 或将谓词限制为单个值时,表被正确消除。这是一个演示该问题的脚本。我在 SQL Server 2016 SP1 中对此进行了测试。
--Create 2 tables for prices; 1 for 2017 and 1 for 2018
CREATE TABLE Price_2017
(
PriceDate DATE NOT NULL,
PriceValue FLOAT NOT NULL
)
GO
ALTER TABLE Price_2017 ADD CONSTRAINT PK_Price_2017 PRIMARY KEY(PriceDate);
GO
ALTER TABLE Price_2017 WITH CHECK ADD CONSTRAINT CK_Price_2017
CHECK (PriceDate >= '2017-01-01' AND PriceDate <= '2017-12-31');
GO
ALTER TABLE Price_2017 CHECK CONSTRAINT CK_Price_2017;
GO
CREATE TABLE Price_2018
(
PriceDate DATE NOT NULL, …Run Code Online (Sandbox Code Playgroud) 我有一个疑问。我想删除这 3 个不同表中的所有选定行 由于我有很多 INNER 连接,我无法弄清楚。我的目标是删除这些卖家 ID 的所有内容。
SELECT *
FROM orders a
INNER JOIN order_items b ON a.order_id = b.order_id
INNER JOIN order_item_histories c ON c.order_item_id = b.order_item_id
WHERE a.seller_id IN (1, 3)
Run Code Online (Sandbox Code Playgroud)
版本 Postgres 10.3
我试过这个,但我无法成功。
DELETE
FROM
USING orders
USING order_items,
USING order_item_histories
WHERE orders.order_id = order_items.order_id AND order_items.order_item_id = order_item_histories.order_item_id
AND orders.seller_id IN (1, 3)
Run Code Online (Sandbox Code Playgroud) 我正在尝试优化服务器的性能,这个特定的查询导致从数据库中读取大量数据,进而导致查询超时。此查询是从 Asp.Net MVC 中的 EF6 生成的。
这是有问题的查询:
exec sp_executesql N'SELECT
[Project1].[C1] AS [C1],
[Project1].[Date] AS [Date],
[Project1].[AssetID] AS [AssetID],
[Project1].[EventData] AS [EventData]
FROM ( SELECT
[Extent1].[AssetID] AS [AssetID],
[Extent1].[Date] AS [Date],
[Extent1].[EventData] AS [EventData],
1 AS [C1]
FROM [dbo].[Alarm] AS [Extent1]
WHERE ([Extent1].[AssetID] IN (cast(''c6e3142e-5b1f-4a91-90d2-03a504e86ece'' as uniqueidentifier), cast(''4de25e8a-7401-49ae-bd6d-0861d67f0d2f'' as uniqueidentifier), cast(''455e3a5f-1091-4784-9964-0a1a54eaa644'' as uniqueidentifier), cast(''04b46c21-c44f-4b67-b64b-12f2764c0448'' as uniqueidentifier), cast(''a350992b-8548-4bf1-bd22-131c114a5343'' as uniqueidentifier), cast(''98ec1f36-cc54-45d2-a0e3-22aa1b669373'' as uniqueidentifier), cast(''27abcf37-2093-43d5-ae62-2e7b10fe4692'' as uniqueidentifier), cast(''c9f43598-2b9c-47b0-9230-37440e6aea54'' as uniqueidentifier), cast(''c5964caa-5c73-4c0e-bb80-4c1dc7e11039'' as uniqueidentifier), cast(''6ac30678-3876-43c9-b708-61ef19b5ea17'' as uniqueidentifier), cast(''e69d870a-87de-4e3d-b4fc-62c962489a7b'' as uniqueidentifier), cast(''a7c2f407-c605-4491-85fe-66c16fc15586'' as uniqueidentifier), …Run Code Online (Sandbox Code Playgroud) performance sql-server optimization parameter-sniffing query-performance
我在这里发生了哈希匹配溢出。我已经用 FULLSCAN 更新了涉及的表的统计信息,所以不是这样。任何指针都非常感谢。
https://www.brentozar.com/pastetheplan/?id=Bkq1VjySm
我使用的是 SQL 2017 Enterprise,内存为 64GB。
performance sql-server optimization execution-plan sql-server-2017 query-performance