我之前使用过完全外部联接来获得我想要的结果,但也许我不完全理解这个概念,因为我无法完成应该是简单的联接。
我有 2 个表(我称之为 t1 和 t2),每个表有 2 个字段:
t1
Policy_Number Premium
101 15
102 7
103 10
108 25
111 3
Run Code Online (Sandbox Code Playgroud)
t2
Policy_Number Loss
101 5
103 9
107 20
Run Code Online (Sandbox Code Playgroud)
我想要做的是从两个表以及 Policy_Number 中获取 Premium 和 Sum of Losses 的总和。我正在使用的代码是:
select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber
from t1 full outer join t2 on t1.policynumber = t2.policynumber
group by t1.policynumber
Run Code Online (Sandbox Code Playgroud)
上面的代码将返回正确的总和,但它会将在“NULL”policy_number 下没有 policy_number 匹配的所有记录分组。
我希望我的结果看起来像这样
Policy_Number Prem_Sum Loss_Sum
107 NULL 20
111 3 NULL
101 15 5
Run Code Online (Sandbox Code Playgroud)
等等.....
我不想要显示 NULL policy_number …
我有一个table1在db1和table2在db2上的SQL Server 2008 R2。
如果我做一个选择查询加入两个表,得到结果真的很慢。
一个简单的查询,如
SELECT *
FROM db1.dbo.table1 t1
LEFT JOIN db2.dbo.table2 t2 ON t1.k1 = t2.k2
Run Code Online (Sandbox Code Playgroud)
有时真的很慢。
我不确定这是否对 SQL Server 很常见,并且“必须像规则一样”“不连接来自不同数据库的两个表”。
在那种情况下......我补充说这个问题,我有一个存储在一个字段上的数据库二进制数据,我喜欢与主数据库分开而不增加主表的大小......最好为此对数据库进行分区?
我用两个简单的表进行了测试,但加入这两个表仍然很慢。
在此先感谢您的帮助。
..几年后更新... 24-09-18
确保您加入的字段具有相同的类型、大小和排序规则。
示例:某些属性是 varchar(255) 和另一个 varchar(20) ......这可能是一个问题,因为引擎必须将一种类型转换为另一种类型(发生隐式转换),而有时它运行得更快......如果重新索引或数据库发生一些变化,你可以看到在某个时刻查询开始花费更多的时间来完成......
如果您无法更改字段类型以匹配其中一个 db/tables,请尝试执行显式转换以查看是否可以提高查询速度。用
cast(fieldname as type(size)) = fieldName2)
我正在研究表连接顺序优化。
在查询处理时,我想获取优化器生成的表连接顺序,并在 PostgreSQL 中使用我自己的算法更新它?
如何在查询处理时更新表连接顺序?
我得到的行比我期望的查询返回的行多。
我相信这与我的 join 语句有关。
有多个表,其中包含不同的信息。 Person保存有关此人的主要信息,但不保存地址、电话或电子邮件。这是因为最初的设计师希望桌子能够容纳多个电话号码、电子邮件和地址。
SELECT (person.FirstName + ' ' + person.LastName) as FullName
,ISNULL(Person.isClient, '')
,ISNULL(Person.UDF1, '')
,ISNULL(Address.City, '')
,ISNULL(Address.state, '')
,PersonAddress.Person
,PersonAddress.Address
,ISNULL(Phone.PhoneNumber, 'N/A')
,Email.Email
,Person.Website
FROM Person
left join PersonAddress on Person.ID = PersonAddress.Person
left join Address on PersonAddress.Address = Address.ID
left join PersonPhone on Person.ID = PersonPhone.Person
left join Phone on PersonPhone.Person = Phone.ID
left join Email with (nolock) on Person.ID = Email.Person
WHERE (
isclient = 'prospect'
or isclient = 'client'
)
and …Run Code Online (Sandbox Code Playgroud) 以下是查询存储遇到的性能问题的简化:
CREATE TABLE #tears
(
plan_id bigint NOT NULL
);
INSERT #tears (plan_id)
VALUES (1);
SELECT
T.plan_id
FROM #tears AS T
LEFT JOIN sys.query_store_plan AS QSP
ON QSP.plan_id = T.plan_id;
Run Code Online (Sandbox Code Playgroud)
该plan_id列被记录为 的主键sys.query_store_plan,但执行计划并不像预期的那样使用连接消除:
plan_id不能复制临时表中的行LEFT JOIN,因此无法T消除from中的任何行。为什么会这样,在这里可以做些什么来消除连接?
performance join sql-server execution-plan query-store query-performance
我有一个带有如下表的 PostgreSQL 9.5.3 DB:
container
id: uuid (pk)
... other data
thing
id: uuid (pk)
... other data
container_thing
container_id: uuid (fk)
thing_id: uuid (fk)
primary key (container_id, thing_id)
Run Code Online (Sandbox Code Playgroud)
Acontainer可以指向任意数量的things(没有重复),并且 athing可以被任意数量的containers指向。
可能有大量的容器和东西(取决于我们有多少客户)。每个容器中可能只有 1 到 10 个东西。我们一次最多只能查询大约 20 个容器。一个容器可以是空的,我需要取回一个空数组。
我需要构建代表容器的 json 对象,如下所示:
{
"id": "d7e1bc6b-b659-432d-b346-29f3a530bfa9",
... other data
"thingIds": [
"4e3ad81b-f2b5-4220-8e0e-e9d53c80a214",
"f26f49e5-76b4-4363-9ffe-9654ba0b0f0d"
]
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我通过使用两个查询来做到这一点:
select * from "container" where "id" in (<list of container ids>)
select * from "container_thing" where "container_id" in …Run Code Online (Sandbox Code Playgroud) 我有 3 个“大”表,它们连接在一对列上(都是ints)。
每个表在Key1、上都有一个聚集索引Key2,然后还有一个列。Key1具有低基数并且非常偏斜。它总是在WHERE子句中被引用。条款中Key2从未提及WHERE。每个连接都是多对多的。
问题在于基数估计。每个连接的输出估计变小而不是变大。当实际结果达到数百万时,这导致最终估计值低至数百。
我有什么办法可以让 CE 做出更好的估计吗?
SELECT 1
FROM Table1 t1
JOIN Table2 t2
ON t1.Key1 = t2.Key1
AND t1.Key2 = t2.Key2
JOIN Table3 t3
ON t1.Key1 = t3.Key1
AND t1.Key2 = t3.Key2
WHERE t1.Key1 = 1;
Run Code Online (Sandbox Code Playgroud)
我尝试过的解决方案:
Key1,Key2join sql-server many-to-many sql-server-2016 cardinality-estimates
快速简单的过滤器问题。
输出会有什么不同,或者将过滤条件从 WHERE 子句移到 Join 条件中会产生什么影响。
例如:
Select a1.Name, a2.State
from student a1
left join location a2 on a1.name_id = a2.name_id
where a1.name LIKE 'A%'
and a2.state = 'New York';
Run Code Online (Sandbox Code Playgroud)
对此:
Select a1.Name, a2.State
from student a1
left join location a2 on (a1.name_id = a2.name_id) and a2.state = 'New York'
where a1.name LIKE 'A%';
Run Code Online (Sandbox Code Playgroud)
谢谢大家。
我有一个包含 2 个反连接(UserEmails = 1M+ 行和Subscriptions = <100k 行)、2 个条件和一个排序的查询。我为2个条件+排序创建了索引,这将查询速度提高了50%。两个反连接都有索引。但是,查询太慢(生产时 4 秒)。
这是查询:
SELECT
"Users"."firstName",
"Users"."lastName",
"Users"."email",
"Users"."id"
FROM
"Users"
WHERE
NOT EXISTS (
SELECT
1
FROM
"UserEmails"
WHERE
"UserEmails"."userId" = "Users". ID
)
AND NOT EXISTS (
SELECT
1
FROM
"Subscriptions"
WHERE
"Subscriptions"."userId" = "Users". ID
)
AND "isEmailVerified" = TRUE
AND "emailUnsubscribeDate" IS NULL
ORDER BY
"Users"."createdAt" DESC
LIMIT 100
Run Code Online (Sandbox Code Playgroud)
这是解释:
Limit (cost=1.28..177.77 rows=100 width=49) (actual time=6171.121..6171.850 rows=100 loops=1)
-> Nested Loop Anti Join …Run Code Online (Sandbox Code Playgroud) join ×10
sql-server ×5
postgresql ×3
many-to-many ×2
performance ×2
array ×1
bigtable ×1
index ×1
json ×1
nosql ×1
optimization ×1
partitioning ×1
query-store ×1
t-sql ×1