我在 Ubuntu 12.04 上使用 PostgreSQL 9.1。
我需要在一个时间范围内选择记录:我的表time_limits有两个timestamp字段和一个integer属性。我的实际表中还有其他列与此查询无关。
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
Run Code Online (Sandbox Code Playgroud)
该表包含大约 200 万条记录。
像下面这样的查询花费了大量的时间:
select * from time_limits as t
where t.id_phi=0
and t.start_date_time <= timestamp'2010-08-08 00:00:00'
and t.end_date_time >= timestamp'2010-08-08 00:05:00';
Run Code Online (Sandbox Code Playgroud)
所以我尝试添加另一个索引 - PK的倒数:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
Run Code Online (Sandbox Code Playgroud)
我的印象是性能有所提高:访问表中间记录的时间似乎更合理:介于 40 到 90 秒之间。
但是对于时间范围中间的值,它仍然是几十秒。在针对表格末尾时(按时间顺序),还有两次。
我explain analyze第一次尝试得到这个查询计划:
Bitmap Heap Scan on time_limits (cost=4730.38..22465.32 rows=62682 width=36) (actual time=44.446..44.446 rows=0 loops=1)
Recheck …Run Code Online (Sandbox Code Playgroud) 我一直在我们的 MS SQL 数据库上运行一个自动索引工具(我修改了一个源自 Microsoft 的脚本,该脚本查看索引统计表 -自动自动索引)。从统计数据中,我现在有一个需要创建的索引的建议列表。
编辑: 上述索引从 DMV 获取信息,这些信息告诉您数据库引擎将用于索引的内容(如果它们可用),并且脚本采用 Top x 推荐(通过搜索、用户影响等)并将它们放在表中。
(上面的编辑部分摘自 Larry Coleman 的回答,以阐明脚本在做什么)
由于我是数据库管理员的新手,并且在网上进行了快速搜索,因此我不愿意冒险并盲目添加推荐的索引。但是,由于没有在该领域的经验,我正在寻找一些关于如何确定这些建议是否必要的建议。
我是否需要运行 SQL Profiler,还是检查查询表的代码更好?你还有什么建议吗?
以下摘自一本关于数据库设计的书(Beginning Database Design ISBN:0-7645-7490-6):
使用视图的危险在于根据视图过滤查询,期望读取非常大的表的非常小的部分。任何过滤都应该在视图中完成,因为在视图中的查询完成执行之后,才会应用针对视图本身的任何过滤。视图通常对加快开发过程很有用,但从长远来看,它会完全扼杀数据库性能。
以下是 PostgreSQL 9.5 文档的摘录:
充分利用视图是良好 SQL 数据库设计的一个关键方面。视图允许您封装表结构的细节,这些细节可能会随着应用程序的发展而改变,并隐藏在一致的接口后面。
这两个来源似乎相互矛盾(“不要用视图设计”与“用视图设计”)。
但是,在 PG 中,视图是使用规则系统实现的。因此,可能(这是我的问题)针对视图的任何过滤都被重写为视图中的过滤器,从而导致对基础表执行单个查询。
我的解释是否正确并且 PG 将 WHERE 子句组合进和出视图?还是单独运行它们,一个接一个?任何简短的、自包含的、正确的(可编译的)示例?
从多个连接创建表以用于分析时,何时首选使用视图而不是创建新表?
我更喜欢使用视图的一个原因是我们的管理员在 Ruby 中开发了数据库模式,而我对 Ruby 并不熟悉。我可以请求创建表,但需要一个额外的步骤,我希望在开发/测试新连接时有更大的灵活性。
我开始使用关于 SO 相关问题的答案的视图(何时使用 R,何时使用 SQL)。得票最多的答案开始于“在 SQL 中进行数据操作,直到数据位于单个表中,然后在 R 中进行其余的操作”。
我已经开始使用视图,但我遇到了一些视图问题:
视图是否适合这种用途?如果是这样,我应该期待性能损失吗?有没有办法加快对视图的查询?
此查询获取您关注的人创建的帖子列表。您可以关注无限数量的人,但大多数人关注 < 1000 人。
使用这种查询方式,明显的优化是缓存"Post"id,但不幸的是我现在没有时间这样做。
EXPLAIN ANALYZE SELECT
"Post"."id",
"Post"."actionId",
"Post"."commentCount",
...
FROM
"Posts" AS "Post"
INNER JOIN "Users" AS "user" ON "Post"."userId" = "user"."id"
LEFT OUTER JOIN "ActivityLogs" AS "activityLog" ON "Post"."activityLogId" = "activityLog"."id"
LEFT OUTER JOIN "WeightLogs" AS "weightLog" ON "Post"."weightLogId" = "weightLog"."id"
LEFT OUTER JOIN "Workouts" AS "workout" ON "Post"."workoutId" = "workout"."id"
LEFT OUTER JOIN "WorkoutLogs" AS "workoutLog" ON "Post"."workoutLogId" = "workoutLog"."id"
LEFT OUTER JOIN "Workouts" AS "workoutLog.workout" ON "workoutLog"."workoutId" = "workoutLog.workout"."id"
WHERE
"Post"."userId" IN …Run Code Online (Sandbox Code Playgroud) postgresql performance index optimization postgresql-performance
我有一个类似如下的查询:
DELETE FROM tblFEStatsBrowsers WHERE BrowserID NOT IN (
SELECT DISTINCT BrowserID FROM tblFEStatsPaperHits WITH (NOLOCK) WHERE BrowserID IS NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
tblFEStatsBrowsers 有 553 行。
tblFEStatsPaperHits 有 47.974.301 行。
tblFEStatsBrowsers:
CREATE TABLE [dbo].[tblFEStatsBrowsers](
[BrowserID] [smallint] IDENTITY(1,1) NOT NULL,
[Browser] [varchar](50) NOT NULL,
[Name] [varchar](40) NOT NULL,
[Version] [varchar](10) NOT NULL,
CONSTRAINT [PK_tblFEStatsBrowsers] PRIMARY KEY CLUSTERED ([BrowserID] ASC)
)
Run Code Online (Sandbox Code Playgroud)
tblFEStatsPaperHits:
CREATE TABLE [dbo].[tblFEStatsPaperHits](
[PaperID] [int] NOT NULL,
[Created] [smalldatetime] NOT NULL,
[IP] [binary](4) NULL,
[PlatformID] [tinyint] NULL,
[BrowserID] [smallint] NULL, …Run Code Online (Sandbox Code Playgroud) 让我们检查这两个语句:
IF (CONDITION 1) OR (CONDITION 2)
...
IF (CONDITION 3) AND (CONDITION 4)
...
Run Code Online (Sandbox Code Playgroud)
如果CONDITION 1是TRUE,会CONDITION 2被检查吗?
如果CONDITION 3是FALSE,会CONDITION 4被检查吗?
条件如何WHERE:SQL Server 引擎是否优化WHERE子句中的所有条件?程序员是否应该以正确的顺序放置条件以确保 SQL Server 优化器以正确的方式解析它?
添加:
感谢 Jack 提供链接,来自 t-sql 代码的惊喜:
IF 1/0 = 1 OR 1 = 1
SELECT 'True' AS result
ELSE
SELECT 'False' AS result
IF 1/0 = 1 AND 1 = 0
SELECT 'True' …Run Code Online (Sandbox Code Playgroud) 我注意到查询子句中的USING构造(而不是ON)可能会在某些情况下引入优化障碍。FROMSELECT
我的意思是这个关键词:
选择 * 从一个 加入 b使用(a_id)
只是在更复杂的情况下。
上下文:this comment to this question。
我用这个了很多,从来没有发现过这么远。我会对展示效果的测试用例或任何指向更多信息的链接非常感兴趣。我的搜索努力是空的。
完美的答案将是一个测试用例,USING (a_id)与替代 join 子句相比,它的性能较差ON a.a_id = b.a_id——如果这真的可以发生的话。
我想按日期范围对 100 万行以上的表进行分区。这通常是如何在不需要大量停机时间或冒丢失数据的风险的情况下完成的?以下是我正在考虑的策略,但欢迎提出建议:
现有的表是主表,子表是从它继承而来的。随着时间的推移,将数据从主表移动到子表,但会有一段时间,其中一些数据在主表中,一些在子表中。
创建一个新的主表和子表。在子表中创建现有表中的数据副本(因此数据将驻留在两个位置)。一旦子表拥有最新数据,更改所有插入以指向新的主表并删除现有表。
对于我尝试优化的中等复杂查询,我注意到删除TOP n子句会更改执行计划。我猜想,当查询包含TOP n数据库引擎时,会运行查询而忽略该TOP子句,然后最后将结果集缩小到请求的n行数。图形执行计划似乎表明情况确实如此——TOP是“最后”一步。但似乎还有更多事情发生。
我的问题是,TOP n 子句如何(以及为什么)影响查询的执行计划?
这是我的情况的简化版本:
查询匹配来自两个表 A 和 B 的行。
如果没有该TOP子句,优化器估计将有来自表 A 的 19k 行和来自表 B 的 46k 行。返回的实际行数是 A 的 16k 和 B 的 13k。哈希匹配用于连接这两个结果集总共 69 行(然后应用排序)。此查询发生得非常快。
当我添加TOP 1001优化器时不使用哈希匹配;相反,它首先对表 A 的结果进行排序(与 19k/16k 相同的估计值/实际值)并对表 B 执行嵌套循环。表 B 的估计行数现在为 1,奇怪的是TOP n直接影响对 B 的估计执行次数(索引搜索) - 它似乎总是2n+1,或者在我的情况下是 2003 年。如果我改变,这个估计会相应地改变TOP n。当然,由于这是嵌套连接,因此实际执行次数为 16k(表 A 中的行数),这会减慢查询速度。
实际场景有点复杂,但这捕获了基本思想/行为。两个表都使用索引查找进行搜索。这是 SQL Server 2008 R2 企业版。
performance sql-server optimization execution-plan query-performance
optimization ×10
postgresql ×5
performance ×4
index ×3
sql-server ×3
view ×2
condition ×1
explain ×1
join ×1
mysql ×1
partitioning ×1
query ×1
select ×1
t-sql ×1