我有一个查询目前平均需要 2500 毫秒才能完成。我的表很窄,但有 4400 万行。我有什么选择可以提高性能,或者这是否已经达到了最好的效果?
查询
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31';
Run Code Online (Sandbox Code Playgroud)
桌子
CREATE TABLE [dbo].[Heartbeats](
[ID] [int] IDENTITY(1,1) NOT NULL,
[DeviceID] [int] NOT NULL,
[IsPUp] [bit] NOT NULL,
[IsWebUp] [bit] NOT NULL,
[IsPingUp] [bit] NOT NULL,
[DateEntered] [datetime] NOT NULL,
CONSTRAINT [PK_Heartbeats] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
指数
CREATE NONCLUSTERED INDEX …Run Code Online (Sandbox Code Playgroud) 相当简单的问题,可能在某处得到了回答,但我似乎无法为 Google 形成正确的搜索问题......
在查询该表的子集时,特定表中的列数是否会影响查询的性能?
例如,如果表 Foo 有 20 列,但我的查询只选择了其中的 5 列,那么有 20(而不是 10)列会影响查询性能吗?为简单起见,假设 WHERE 子句中的任何内容都包含在这 5 列中。
除了操作系统的磁盘缓存之外,我还担心 Postgres 的缓冲区缓存的使用。我对 Postgres 的物理存储设计一无所知。表存储在多个页面上(默认为每页 8k 大小),但我不太明白元组是如何从那里排列的。PG 是否足够聪明,只能从磁盘中获取包含这 5 列的数据?
在诊断基数估计不佳的 SQL Server 2008 R2 查询(尽管有简单的索引、最新的统计数据等)和查询计划不佳时,我发现了一篇可能相关的知识库文章: FIX:运行查询时性能不佳包含 SQL Server 2008 或 SQL Server 2008 R2 或 SQL Server 2012 中的关联 AND 谓词
我可以猜测知识库文章中“相关”的含义,例如谓词#2 和谓词#1 主要针对相同的行。
但我不知道 SQL Server 是如何知道这些相关性的。表是否需要包含来自两个谓词的列的多列索引?SQL 是否使用统计信息来检查一列中的值是否与另一列相关?还是使用了其他方法?
我问这个有两个原因:
performance sql-server statistics sql-server-2008-r2 query-performance
在某些情况下,需要非常大的查询将多个表与其中的子选择语句连接在一起以产生所需的结果。
我的问题是,我们是否应该考虑使用多个较小的查询,并通过多次调用查询数据库将逻辑操作带入应用程序层,还是最好一次性完成所有操作?
例如,考虑以下查询:
SELECT *
FROM `users`
WHERE `user_id` IN (SELECT f2.`friend_user_id`
FROM `friends` AS f1
INNER JOIN `friends` AS f2
ON f1.`friend_user_id` = f2.`user_id`
WHERE f2.`is_page` = 0
AND f1.`user_id` = "%1$d"
AND f2.`friend_user_id` != "%1$d"
AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
FROM `friends`
WHERE `user_id` = "%1$d"))
AND `user_id` NOT IN (SELECT `user_id`
FROM `friend_requests`
WHERE `friend_user_id` = "%1$d")
AND `user_image` IS NOT NULL
ORDER BY RAND()
LIMIT %2$d
Run Code Online (Sandbox Code Playgroud)
最好的方法是什么?
我正在尝试确定哪些索引用于带有WHERE条件的 SQL 查询,GROUP BY而当前运行速度很慢。
我的查询:
SELECT group_id
FROM counter
WHERE ts between timestamp '2014-03-02 00:00:00.0' and timestamp '2014-03-05 12:00:00.0'
GROUP BY group_id
Run Code Online (Sandbox Code Playgroud)
该表目前有 32.000.000 行。当我增加时间范围时,查询的执行时间会增加很多。
有问题的表如下所示:
CREATE TABLE counter (
id bigserial PRIMARY KEY
, ts timestamp NOT NULL
, group_id bigint NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
我目前有以下索引,但性能仍然很慢:
CREATE INDEX ts_index
ON counter
USING btree
(ts);
CREATE INDEX group_id_index
ON counter
USING btree
(group_id);
CREATE INDEX comp_1_index
ON counter
USING btree
(ts, group_id);
CREATE INDEX comp_2_index
ON counter …Run Code Online (Sandbox Code Playgroud) postgresql performance index optimization postgresql-9.3 query-performance
我正在使用 Postgres 9.3.5 并且我在数据库中有一个大表,目前它有超过 2500 万行,而且它往往会迅速变大。我正在尝试使用一个简单的查询来选择特定的行(所有unit_ids 都只有最新unit_timestamp的),例如:
SELECT unit_id, max(unit_timestamp) AS latest_timestamp FROM all_units GROUP BY unit_id;
Run Code Online (Sandbox Code Playgroud)
在没有任何索引的情况下,此查询大约需要 35 秒才能执行。定义索引 ( CREATE INDEX partial_idx ON all_units (unit_id, unit_timestamp DESC);) 后,查询时间缩短到(仅)19 秒左右。
我想知道是否有可能在更短的时间内(比如几秒钟)执行我的查询,如果是这样,我应该采取哪些步骤来进一步优化它?
我的表结构转储如下所示:
CREATE TABLE "all_units" (
"unit_id" int4 NOT NULL,
"unit_timestamp" timestamp(6) NOT NULL,
"lon" float4,
"lat" float4,
"speed" float4,
"status" varchar(255) COLLATE "default"
)
ALTER TABLE "all_units" ADD PRIMARY KEY ("unit_id", "unit_timestamp");
Run Code Online (Sandbox Code Playgroud)
该EXPLAIN (ANALYZE, BUFFERS)如下:
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=663998.38..664069.73 rows=7135 …Run Code Online (Sandbox Code Playgroud) 我遇到了一个查询的性能问题,我似乎无法理解。
我从游标定义中提取了查询。
此查询需要几秒钟才能执行
SELECT A.JOBTYPE
FROM PRODROUTEJOB A
WHERE ((A.DATAAREAID=N'IW')
AND ((A.CALCTIMEHOURS<>0)
AND (A.JOBTYPE<>3)))
AND EXISTS (SELECT 'X'
FROM PRODROUTE B
WHERE ((B.DATAAREAID=N'IW')
AND (((((B.PRODID=A.PRODID)
AND ((B.PROPERTYID=N'PR1526157') OR (B.PRODID=N'PR1526157')))
AND (B.OPRNUM=A.OPRNUM))
AND (B.OPRPRIORITY=A.OPRPRIORITY))
AND (B.OPRID=N'GRIJZEN')))
AND NOT EXISTS (SELECT 'X'
FROM ADUSHOPFLOORROUTE C
WHERE ((C.DATAAREAID=N'IW')
AND ((((((C.WRKCTRID=A.WRKCTRID)
AND (C.PRODID=B.PRODID))
AND (C.OPRID=B.OPRID))
AND (C.JOBTYPE=A.JOBTYPE))
AND (C.FROMDATE>{TS '1900-01-01 00:00:00.000'}))
AND ((C.TODATE={TS '1900-01-01 00:00:00.000'}))))))
GROUP BY A.JOBTYPE
ORDER BY A.JOBTYPE
Run Code Online (Sandbox Code Playgroud)
实际的执行计划是这样的。

注意到服务器范围的设置被设置为 MaxDOP 1,我尝试使用 maxdop 设置。
添加OPTION (MAXDOP 0)到查询或更改服务器设置会导致更好的性能和此查询计划。

但是,有问题的应用程序(Dynamics AX)不会执行这样的查询,它使用游标。 …
performance sql-server parallelism cursors microsoft-dynamics query-performance
我正在优化一些查询。
对于下面的查询,
SET STATISTICS IO ON;
DECLARE @OrderStartDate DATETIME2 = '27 feb 2016';
DECLARE @OrderEndDate DATETIME2 = '28 feb 2016';
SELECT o.strBxOrderNo
, o.sintOrderStatusID
, o.sintOrderChannelID
, o.sintOrderTypeID
, o.sdtmOrdCreated
, o.sintMarketID
, o.strOrderKey
, o.strOfferCode
, o.strCurrencyCode
, o.decBCShipFullPrice
, o.decBCShipFinal
, o.decBCShipTax
, o.decBCTotalAmount
, o.decWrittenTotalAmount
, o.decBCWrittenTotalAmount
, o.decBCShipOfferDisc
, o.decBCShipOverride
, o.decTotalAmount
, o.decShipTax
, o.decShipFinal
, o.decShipOverride
, o.decShipOfferDisc
, o.decShipFullPrice
, o.lngAccountParticipantID
, CONVERT(DATE, o.sdtmOrdCreated, 120) as OrderCreatedDateConverted
FROM tablebackups.dbo.tblBOrder o
WHERE o.sdtmOrdCreated >= …Run Code Online (Sandbox Code Playgroud) performance sql-server optimization index-tuning sql-server-2014 query-performance
下面的查询执行时间超过 11 分钟。
SELECT `c`.*,
`e`.`name` AS `employee_name`,
`e`.`emp_no`,
`d`.`code` AS `department_code`,
IF(ew.code IS NOT NULL, ew.code, egw.code) AS shift_code,
IF(ew.code IS NOT NULL, ew.time_in_from, egw.time_in_from) AS time_in_from,
IF(ew.code IS NOT NULL, ew.time_out_to, egw.time_out_to) AS time_out_to,
IF(ew.code IS NOT NULL, ew.next_day, egw.next_day) AS next_day
FROM `tms_emp_badge_card` AS `c`
LEFT JOIN `tms_door_record_raw` AS `dr`
ON `c`.`card_no` = `dr`.`card_no`
LEFT JOIN `tms_employee` AS `e`
ON `c`.`emp_no` = `e`.`emp_no`
LEFT JOIN `tms_emp_group` AS `g`
ON `e`.`group_id` = `g`.`id`
LEFT JOIN `tms_emp_department` AS `d` …Run Code Online (Sandbox Code Playgroud) 让我们做几个假设:
我有一个看起来像这样的表:
a | b
---+---
a | -1
a | 17
...
a | 21
c | 17
c | -3
...
c | 22
Run Code Online (Sandbox Code Playgroud)
关于我的套装的事实:
整个表的大小是 ~ 10 10行。
我有 ~ 100k 行,列中有值a,a其他值类似(例如c)。
这意味着在“a”列中有大约 100k 个不同的值。
我的大多数查询都会读取 a 中给定值的全部或大部分值,例如select sum(b) from t where a = 'c'.
该表的编写方式使得连续值在物理上接近(要么按顺序写入,要么我们假设CLUSTER已在该表和列上使用a)。
该表很少更新,我们只关心读取速度。
该表相对较窄(比如每个元组约 25 个字节,+ 23 个字节的开销)。
现在的问题是,我应该使用什么样的索引?我的理解是:
BTree我的问题是 BTree 索引会很大,因为据我所知它会存储重复值(它必须这样做,因为它不能假设表是物理排序的)。如果 BTree 很大,我最终不得不读取索引和索引指向的表部分。(我们可以使用fillfactor = 100来稍微减小索引的大小。)
BRIN …
postgresql performance index clustered-index postgresql-9.6 query-performance
performance ×10
optimization ×4
postgresql ×4
sql-server ×4
index ×3
mysql ×2
cursors ×1
index-tuning ×1
join ×1
parallelism ×1
scalability ×1
statistics ×1