2020-08-04 更新:
由于显然仍在定期查看此答案,因此我想提供有关情况的最新信息。我们目前正在使用带有表分区的 PG 11,timestamp并且可以轻松处理表中的数十亿行。仅索引扫描可以挽救生命,没有它就不可能。
使用 PostgreSQL 9.2,我在相对较大的表(200 多万行)上进行慢速查询时遇到问题。我没有尝试任何疯狂的事情,只是增加了历史价值。下面是查询和查询计划输出。
我的表布局:
Table "public.energy_energyentry"
Column | Type | Modifiers
-----------+--------------------------+-----------------------------------------------------------------
id | integer | not null default nextval('energy_energyentry_id_seq'::regclass)
prop_id | integer | not null
timestamp | timestamp with time zone | not null
value | double precision | not null
Indexes:
"energy_energyentry_pkey" PRIMARY KEY, btree (id)
"energy_energyentry_prop_id" btree (prop_id)
"energy_energyentry_prop_id_timestamp_idx" btree (prop_id, "timestamp")
Foreign-key constraints:
"energy_energyentry_prop_id_fkey" FOREIGN KEY (prop_id) REFERENCES gateway_peripheralproperty(id) DEFERRABLE INITIALLY DEFERRED
Run Code Online (Sandbox Code Playgroud)
数据范围从2012-01-01至今,新数据不断增加。prop_id外键中大约有 2.2k 个不同的值,均匀分布。
我注意到行估计值相差不远,但成本估计值似乎大了 …
postgresql performance index optimization postgresql-performance
我在 PCMag 中阅读了 Itzik Ben-Gan 的这些文章:
搜索,您应扫描第 I 部分:当优化器未优化
搜索时,您应扫描第 II 部分:升序键
我目前的所有分区表都存在“最大分组”问题。我们使用Itzik Ben-Gan 提供的技巧来获取 max(ID),但有时它不会运行:
DECLARE @MaxIDPartitionTable BIGINT
SELECT @MaxIDPartitionTable = ISNULL(MAX(IDPartitionedTable), 0)
FROM ( SELECT *
FROM ( SELECT partition_number PartitionNumber
FROM sys.partitions
WHERE object_id = OBJECT_ID('fct.MyTable')
AND index_id = 1
) T1
CROSS APPLY ( SELECT ISNULL(MAX(UpdatedID), 0) AS IDPartitionedTable
FROM fct.MyTable s
WHERE $PARTITION.PF_MyTable(s.PCTimeStamp) = PartitionNumber
AND UpdatedID <= @IDColumnThresholdValue
) AS o
) AS T2;
SELECT @MaxIDPartitionTable
Run Code Online (Sandbox Code Playgroud)
我得到这个计划
但是 45 分钟后,看看读数
reads …Run Code Online (Sandbox Code Playgroud) 比如说,我们有一个这样的查询:
select a.*,b.*
from
a join b
on a.col1=b.col1
and len(a.col1)=10
Run Code Online (Sandbox Code Playgroud)
假设上述查询使用 Hash Join 并具有残差,则探测键将为col1,残差将为len(a.col1)=10。
但是在查看另一个示例时,我可以看到探针和残差是同一列。以下是对我想说的内容的详细说明:
询问:
select *
from T1 join T2 on T1.a = T2.a
Run Code Online (Sandbox Code Playgroud)
执行计划,突出显示探测和残差:
测试数据:
create table T1 (a int, b int, x char(200))
create table T2 (a int, b int, x char(200))
set nocount on
declare @i int
set @i = 0
while @i < 1000
begin
insert T1 values (@i * 2, @i * 5, @i)
set @i = @i …Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan database-internals query-performance
我有一个存储过程,它通过覆盖索引从索引视图返回结果。通常,它运行得很快(~10 毫秒),有时它可以运行长达 8 秒。
这是一个随机执行示例(注意:这不是一个缓慢的执行,但是除了传递的值之外,查询文本是相同的):
declare @p2 dbo.IdentityType
insert into @p2 values(5710955)
insert into @p2 values(5710896)
insert into @p2 values(5710678)
insert into @p2 values(5710871)
insert into @p2 values(5711103)
insert into @p2 values(6215197)
insert into @p2 values(5710780)
exec ListingSearch_ByLocationAndStatus @statusType=1,@locationIds=@p2
Run Code Online (Sandbox Code Playgroud)
这是 SPROC:
ALTER PROCEDURE [dbo].[ListingSearch_ByLocationAndStatus]
@LocationIds IdentityType READONLY,
@StatusType TINYINT
AS
BEGIN
SET NOCOUNT ON;
SELECT -- lots of fields
FROM [dbo].[ListingSearchView][a] WITH (NOEXPAND)
INNER JOIN @LocationIds [b] ON [a].[LocationId] = [b].[Id]
WHERE [a].[StatusType] = @statusType
OPTION (RECOMPILE);
Run Code Online (Sandbox Code Playgroud)
(注意:我OPTION (RECOMPILE) …
performance sql-server sql-server-2012 azure-vm query-performance
RDBMS 系统是否针对COMMIT操作进行了优化?ROLLBACK操作慢/快多少?为什么?
有人向我建议,在 t-SQL 批处理中使用 IF 语句对性能有害。我试图找到一些确认或验证这个断言。我使用的是 SQL Server 2005 和 2008。
断言是以下批次:-
IF @parameter = 0
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
Run Code Online (Sandbox Code Playgroud)
SQL Server 无法重用生成的执行计划,因为下一次执行可能需要不同的分支。这意味着 SQL Server 将从执行计划中完全删除一个分支,因为它已经可以确定当前执行需要哪个分支。这是真的吗?
此外,在这种情况下会发生什么:-
IF EXISTS (SELECT ....)
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
Run Code Online (Sandbox Code Playgroud)
无法提前确定将执行哪个分支?
performance sql-server-2005 sql-server-2008 sql-server query-performance
我有一个带有“TOP (X)”子句的 SQL UPDATE 语句,我正在更新值的行大约有 40 亿行。当我使用“TOP (10)”时,我得到一个几乎立即执行的执行计划,但是当我使用“TOP (50)”或更大时,查询永远不会(至少,在我等待时不会)完成,并且它使用完全不同的执行计划。较小的查询使用带有一对索引查找和嵌套循环连接的非常简单的计划,其中完全相同的查询(在 UPDATE 语句的 TOP 子句中具有不同的行数)使用涉及两个不同索引查找的计划、表线轴、并行性和一堆其他复杂性。
我使用了“OPTION (USE PLAN...)”来强制它使用由较小查询生成的执行计划——当我这样做时,我可以在几秒钟内更新多达 100,000 行。我知道查询计划很好,但 SQL Server 只会在只涉及少量行时自行选择该计划 - 我的更新中任何相当大的行数都会导致次优计划。
我认为并行性可能是罪魁祸首,所以我设置MAXDOP 1了查询,但没有效果 - 这一步已经消失,但糟糕的选择/性能没有。我sp_updatestats今天早上也跑了,以确保这不是原因。
我附上了两个执行计划 - 越短的执行计划也越快。此外,这里是有问题的查询(值得注意的是,我包含的 SELECT 在小行数和大行数的情况下似乎都很快):
update top (10000) FactSubscriberUsage3
set AccountID = sma.CustomerID
--select top 50 f.AccountID, sma.CustomerID
from FactSubscriberUsage3 f
join dimTime t
on f.TimeID = t.TimeID
join #mac sma
on f.macid = sma.macid
and t.TimeValue between sma.StartDate and sma.enddate
where f.AccountID = 0 --There's a filtered index …Run Code Online (Sandbox Code Playgroud) 最后是一个测试脚本,用于比较@table 变量和#temp 表之间的性能。我想我已经正确设置了 - 性能计时是在 DELETE/TRUNCATE 命令之外进行的。我得到的结果如下(以毫秒为单位)。
@Table Variable #Temp (delete) #Temp (truncate)
--------------- -------------- ----------------
5723 5180 5506
15636 14746 7800
14506 14300 5583
14030 15460 5386
16706 16186 5360
Run Code Online (Sandbox Code Playgroud)
只是为了确保我是理智的,这表明 CURRENT_TIMESTAMP (aka GetDate()) 是在语句时使用的,而不是批处理时,因此 TRUNCATE/DELETE 与SET @StartTime = CURRENT_TIMESTAMP语句之间不应有交互。
select current_timestamp
waitfor delay '00:00:04'
select current_timestamp
-----------------------
2012-10-21 11:29:20.290
-----------------------
2012-10-21 11:29:24.290
Run Code Online (Sandbox Code Playgroud)
当使用 DELETE 清除表时,第一次运行和后续运行之间的跳转非常一致。我对DELETE 的理解缺少什么?我已经重复了很多次,交换了顺序,调整了 tempdb 的大小以使其不需要增长等。
CREATE TABLE #values (
id int identity primary key, -- will be clustered …Run Code Online (Sandbox Code Playgroud) 最近包含 SQL Server 启动跟踪标志 8048 以解决 SQL Server 2008 R2 系统中严重的自旋锁争用问题。
有兴趣听取其他人的意见,他们发现性能值由跟踪标志 8048(将查询内存授予策略从每个 NUMA 节点提升到每个核心)、跟踪标志 8015(SQL Server 忽略物理 NUMA)或 SUMA(交错足够统一的内存访问,某些 NUMA 机器上的 BIOS 选项)。
系统工作负载的详细信息、从出现问题的系统收集的指标以及在干预后从系统收集的指标。
跟踪标志 8048 是一个“修复”,但它是最好的修复吗?SQL Server 是否会因为跟踪标志 8015 而忽略物理 NUMA 已经完成了同样的事情?如何将 BIOS 设置为交错内存,让服务器使用 SMP 模拟 SUMA 行为而不是 NUMA 行为?
从 …
我想在我的 MySQL 数据库中存储一些几何位置。为此,我使用 POINT 数据类型。我读到的几乎所有地方都GeomFromText应该使用该函数在表中插入数据。
但是,我发现这POINT(X,Y)也有效。我没有找到任何说明为什么GeomFromText应该使用POINT.
例如,我有以下简单的关系:
CREATE TABLE Site (
SiteID BIGINT UNSIGNED,
Position POINT
);
Run Code Online (Sandbox Code Playgroud)
我可以使用以下两种变体插入值:
INSERT INTO Site (
1,
GeomFromText( 'POINT(48.19976 16.45572)' )
);
INSERT INTO Site (
2,
POINT(48.19976, 16.45572)
);
Run Code Online (Sandbox Code Playgroud)
当我查看表 ( SELECT * FROM Site) 时,我会看到该位置的相同二进制 blob,而当我查看坐标 ( SELECT *, AsText(Position) FROM Site) 时,我也会看到相同的值。
那么为什么要使用 GeomFromText 呢?这两种变体之间是否存在任何(已知的)性能差异?这是如何在除 MySQL 之外的其他数据库系统中解决的?
performance ×10
sql-server ×7
azure-vm ×1
delete ×1
index ×1
memory ×1
mysql ×1
numa ×1
optimization ×1
partitioning ×1
postgresql ×1
rdbms ×1
rollback ×1
spatial ×1
transaction ×1
truncate ×1