我有一个连接多个表的视图,只是为了简化一个经常调用的查询。此视图在计算字段上有一个 ORDER BY 子句(顺序永远不会不同)。(在 SQL Server Express 2008 R2 上)。
基本思路是这样的(简化):
SELECT [EventType].Name,
[EventType].TotalOccurrences,
[Session].ID,
[Session].TotalOccurrences,
[Session].TotalOccurrences / [EventType].TotalOccurrences AS saturation
FROM [EventType]
INNER JOIN [Session] ON [EventType].ID = [Session].Event
ORDER BY saturation
Run Code Online (Sandbox Code Playgroud)
但是,如果没有 where 子句,则永远不会调用此视图(在我的情况下,它几乎会返回整个数据库)。它将永远与WHERE [EventType].ID = x. 但是,一旦我添加了 where 子句,就会忽略 ORDER BY 子句!如果没有 where 子句,它会按预期工作。
实际上是一个不同的问题,但我在处理的时候把它扔在这里,有没有更好的方法来检索这些信息?的[EventType].Name和[EventType].TotalOccurrences将是所有返回的行,这是网络带宽小腰相同。这不是问题,但我想知道是否有任何方法可以解决这个问题,而没有多次往返数据库的延迟开销?
[编辑] 上面的示例过于简化,计算字段有其他因素,因此它会返回与ORDER BY [Session].TotalOccurrences本示例中的简单顺序不同的顺序,但原理应该很清楚。
[Edit2] 从答案我得出的结论是,图形设计器比底层数据库具有更多的功能:

目前我创建了一个视图,请在答案中查看。如何根据该crosstab()查询创建函数,以便传递日期并获取特定日期的数据?
多次调用该函数并传递不同的日期来填充图表(例如)也是一种好习惯吗?
使用 Postgres 9.4,我经常执行以下查询:
SELECT DISTINCT ON(recipient) * FROM messages
LEFT JOIN identities ON messages.recipient = identities.name
WHERE timestamp BETWEEN timeA AND timeB
ORDER BY recipient, timestamp DESC;
Run Code Online (Sandbox Code Playgroud)
所以我决定创建一个视图:
CREATE VIEW myView AS SELECT DISTINCT ON(recipient) * FROM messages
LEFT JOIN identities ON messages.recipient = identities.name
ORDER BY recipient, timestamp DESC;
Run Code Online (Sandbox Code Playgroud)
我刚刚意识到,如果我查询我的观点,就像SELECT * FROM myView WHERE timestamp BETWEEN timeA AND timeB我的表现要差很多一样。
这样EXPLAIN ANALYZE两个问题,我发现了原因是,在第二种情况下,数据库带来了所有记录,请问左连接,然后应用WHERE条款。换句话说,WHERE子句不会被下推到视图的查询中。我还尝试ORDER BY从视图中删除,但数据库仍然LEFT JOIN对完整数据而不是过滤集执行。
这种行为的原因是什么?有没有办法在使用视图时获得可比较的性能?
我正在尝试修改共享开发数据库,供开发团队用于应用程序开发/测试。
大多数集体工作(表名、视图等)都存储在公共环境中模式中,但我已经为每个用户设置了模式以用作临时空间。然而,真正的目标是用户使用其架构中的对象(如果存在),然后依赖其他对象,就像今天使用 search_path 的方式一样。
用一个例子可能会更好地描述这一点。假设团队正在开发一个汽车维修应用程序的数据库,其中包含一些表和视图:
public.automobiles
public.parts
public.inventory
public.mechanics
public.schedule
public.v_repairs -- view that joins fields from all tables above
Run Code Online (Sandbox Code Playgroud)
这非常有效,但假设开发人员(例如 Sally)想要测试一项新功能,用她自己的数据集来检查视觉反馈或阈值测试。她在自己的架构中创建了一个表sally.schedule。因为默认的search_path类似于"$user",public,所以她创建的任何简单查询都会在公开之前首先检查她的架构。例如:
SELECT * FROM schedule LEFT JOIN mechanics USING(mechanic_id);
Run Code Online (Sandbox Code Playgroud)
当 sally 连接到数据库时,这将使用 public.mechanics 和 sally.schedule。这正是预期的用途,但是在保存视图时,它通过插入架构来完全限定表名称。因此,如果将上面相同的查询创建为公共模式中的视图,它将如下所示:
SELECT * FROM public.schedule LEFT JOIN public.mechanics USING(mechanic_id);
Run Code Online (Sandbox Code Playgroud)
search_path 的魔力被否定了。当Sally连接到数据库调用视图时(SELECT * FROM v_mechanics_schedule ) 时,它会忽略她创建的 sally.schedule 表,而只使用公共表。
有没有办法在保存视图时不让 Postgres 存储表/视图对象的架构名称?
注意:这是我正在研究的新事物,但我从未真正需要过它,因为开发人员通常可以克隆应用程序、复制数据库并在自己的沙箱环境中工作。不需要一些巧妙的协作模式设置
架构绑定视图会影响 SQL Server 中的性能还是只是为了防止意外更改?
我们正在使用商业智能系统,需要加载日期列表,以便我们可以将它们标记为“上周”或“过去 12 个月”或某些动态值。
我想知道虚拟生成一个表的最简单方法是什么,该表仅在一列中列出日期,实际上是从“2014-01-01”到当前日期的每个日期(其他列我可以使用那里的公式)。实际上,甚至将未来的日期附加一年也可能很有用。
现在,是的,我可以从另一个具有数千个条目的随机事实表中获取不同的日期,但这似乎很草率,并且正在创建一种真正不应该存在的依赖关系。
当我使用设计视图创建或编辑查询时,SSMS 会无缘无故地为某些表创建别名 (TableName_1) 。更烦人的是,如果我在设计视图中打开现有查询,它也会这样做。换句话说,它改变了我的 SQL 代码!即使是简单的查询也有这个问题,例如:
SELECT
dbo.tblCalendar.id,
dbo.tblCalendar.title,
dbo.luCalendarType.typeName
FROM
dbo.luCalendarType RIGHT OUTER JOIN
dbo.tblCalendar ON dbo.luCalendarType.id = dbo.tblCalendar.type
Run Code Online (Sandbox Code Playgroud)
将成为:
SELECT
dbo.tblCalendar.id,
dbo.tblCalendar.title,
luCalendarType_1.typeName
FROM
dbo.luCalendarType AS luCalendarType_1 RIGHT OUTER JOIN
dbo.tblCalendar ON luCalendarType_1.id = dbo.tblCalendar.typeRun Code Online (Sandbox Code Playgroud)
有什么办法可以阻止 SSMS 改变我的 SQL 代码?
我正在构建的视图每周都变得越来越复杂和大。它的想法是拥有多个管理报告的来源,包括其中一些人进行的临时查询(会计师 - 我能说什么)。我不担心服务器上的负载 - 这个服务器专门用于此,所以需要一段时间才能使用任何重要的资源。但是在它上面做任何事情都需要越来越长的时间。
它大约有 30% 的计算字段,目前有 25 个连接,我可以删除其中的 8 个,但在某些时候会添加更多。无法对其进行索引,因为它跨越 4 个不同的数据库(目前),因此性能充其量只是龟龟。
所以我想按计划将视图的内容转储到表中,问题是:有没有更好的方法?如果没有,需要注意哪些障碍?
编辑:数据过时:直到前一天。数据范围:所有行,不幸的是,当前计数为 320 万。此外,还有开发阶段的问题——现在我们正在研究我们需要、想要和想要的东西,所以性能调整是毫无意义的 ATT。索引将是一个好的开始,但不是现在这个观点。拆分为多个视图/查询听起来不错,但不会从任何有意义的意义上减少执行时间(减少 20 分钟听起来很棒,直到您意识到起点是 75 分钟)。
我正在使用的数据已通过 SSIS 包从其他数据库(和服务器)复制。对其进行改造以将数据整合到一个数据库中可能是可行的,但这不是我的权限。这可能涉及财务成本,并且在所有开发工作完成之前将被管理层拒绝。
我只知道我需要大大加快速度。可能很脏。除非我会花更多的时间等待查询执行而不是适当的开发。
performance sql-server view sql-server-2012 query-performance
我正在尝试使用视图替换我们应用程序中的表。它在大多数情况下运行良好,但我无法克服这个错误:“列必须出现在 GROUP BY 子句中或用于聚合函数中”
重现步骤:
CREATE TABLE example_t (
did serial PRIMARY KEY,
a text,
b text
);
INSERT INTO example_t(a, b) VALUES ('a', 'b');
CREATE VIEW example_t_v AS
SELECT t.did as did, t.a as a, t.b as b
FROM example_t t;
Run Code Online (Sandbox Code Playgroud)
现在这个查询工作正常:
SELECT t.a, t.b FROM example_t t GROUP BY (t.did);
Run Code Online (Sandbox Code Playgroud)
但是来自视图的相同查询失败:
SELECT t.a, t.b FROM example_t_v t GROUP BY (t.did);
ERROR: column "t.a" must appear in the GROUP BY clause or be used in an aggregate function
LINE …Run Code Online (Sandbox Code Playgroud) 我有一张桌子,Id作为主键。
create table Anything
(
Id bigint not null primary key identity(1, 1)
)
Run Code Online (Sandbox Code Playgroud)
当我查看 中的这张表时Object Explorer,我当然会看到这张图片:
正如你所看到的,列Id是不为空。
然后我在这个虚拟表上创建一个虚拟视图:
create view IdIsTwoView
as
select
Id,
(
case
when Id = 2
then cast(1 as bit)
else cast(0 as bit)
end
) as IdIsTwo
from Anything
Run Code Online (Sandbox Code Playgroud)
但这一次,在对象资源管理器中,我看到了这个结果:
如您所见,尽管我的case子句包罗万象,涵盖了所有记录的 100%,并且对所有记录都有答案,但它可以为空。
为什么 SQL Server 有这种奇怪的行为?我如何强制它不为 null?
PS我们有一个动态生成代码的基础设施,这种行为给我们带来了麻烦,我们必须手动将bool?C# 中的所有类型更改为bool.
view ×10
sql-server ×6
postgresql ×4
performance ×3
date ×1
functions ×1
null ×1
optimization ×1
order-by ×1
ssms ×1
t-sql ×1