我对一个有 1.5M 行的表有一个相对简单的查询:
SELECT mtid FROM publication
WHERE mtid IN (9762715) OR last_modifier=21321
LIMIT 5000;
Run Code Online (Sandbox Code Playgroud)
EXPLAIN ANALYZE 输出:
Run Code Online (Sandbox Code Playgroud)Limit (cost=8.84..12.86 rows=1 width=8) (actual time=0.985..0.986 rows=1 loops=1) -> Bitmap Heap Scan on publication (cost=8.84..12.86 rows=1 width=8) (actual time=0.984..0.985 rows=1 loops=1) Recheck Cond: ((mtid = 9762715) OR (last_modifier = 21321)) -> BitmapOr (cost=8.84..8.84 rows=1 width=0) (actual time=0.971..0.971 rows=0 loops=1) -> Bitmap Index Scan on publication_pkey (cost=0.00..4.42 rows=1 width=0) (actual time=0.295..0.295 rows=1 loops=1) Index Cond: (mtid = 9762715) -> Bitmap Index Scan on …
我正在寻找一种创建查询以执行以下操作的方法:
让我们考虑 3 个表:
让我们考虑每个表的这种结构:
产品:
标签:
标签关系:
我想要的是:
例如,获取所有标记为标签 id 10、11 和 12 的产品。
此查询不起作用,因为它返回至少具有以下标签之一的产品:
select
p.name as name,
p.id as id
from
products p inner join tag_ties ties
on
p.id=ties.ref_id
where
ties.ref_id=p.id and
ties.tag_id in (10,11,12)
group by
p.id
order by
p.name asc
Run Code Online (Sandbox Code Playgroud) 我刚刚建立了一个日志系统,它由多个具有相同布局的表组成。
每个数据源有一个表。
对于日志查看器,我想
所有表都包含一个称为zeitpunkt索引日期/时间列的字段。
我的第一次尝试是:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730)
ORDER BY zeit DESC LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
优化器无法使用此处的索引,因为来自两个表的所有行都由子查询返回并在UNION.
我的解决方法如下:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source …Run Code Online (Sandbox Code Playgroud) 我编写了一个 SQL Server 查询,它在对字段进行分区后更新记录以具有序列号。当我将它作为 SELECT 语句运行时,一切看起来都很棒:
DECLARE @RunDetailID INT = 448
DECLARE @JobDetailID INT
SELECT @JobDetailID = [JobDetailID] FROM [RunDetails] WHERE [RunDetailID] = @RunDetailID
SELECT
[OrderedRecords].[NewSeq9],
RIGHT([OrderedRecords].[NewSeq9], 4)
FROM
(
SELECT
[Records].*,
[Records].[SortField] + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY [Records].[SortField] ORDER BY [Records].[RunDetailID], [Records].[SortField], [Records].[PieceID]) AS VARCHAR), 4) NewSeq9
FROM
(
SELECT
[MRDFStorageID],
[RunDetailID],
[SortField],
[PieceID],
[Seq9],
[BallotType]
FROM
[MRDFStorage]
JOIN [BallotStyles] ON [MRDFStorage].[SortField] = [BallotStyles].[Style] and [BallotStyles].[JobDetailID] = @JobDetailID
WHERE
[RunDetailID] IN (SELECT [RunDetailID] FROM [RunDetails] WHERE [JobDetailID] = …Run Code Online (Sandbox Code Playgroud) 我的函数接受一个int4作为参数并返回一个表:
SELECT * FROM test_function(545421); -- works fine
SELECT * FROM test_function(SELECT customerid
FROM tableX where id = 1); -- syntax error
Run Code Online (Sandbox Code Playgroud)
我怎样才能使这项工作?
服务器 PostgreSQL 9.3.1
查询 1:
select distinct email from mybigtable where account_id=345
Run Code Online (Sandbox Code Playgroud)
需要 0.1 秒
查询 2:
Select count(*) as total from mybigtable where account_id=123 and email IN (<include all from above result>)
Run Code Online (Sandbox Code Playgroud)
需要 0.2 秒
查询 3:
Select count(*) as total from mybigtable where account_id=123 and email IN (select distinct email from mybigtable where account_id=345)
Run Code Online (Sandbox Code Playgroud)
需要 22 分钟,其中 90% 处于“准备”状态。为什么要花这么多时间。
表是 innodb,在 MySQL 5.0 上有 320 万行
mysql innodb performance optimization subquery query-performance
我有两个表:search_criteria和pricing。
表中的列和表中的search_id列都有一个索引。search_criteriapricing_idpricing
但是运行这个嵌套查询不会在search_criteria表上使用索引。
explain
select *
from search_criteria USE INDEX (idx_search_id)
where search_id in
(select search_id
from pricing
where pricing_id = '009330be-d041-444f-a624-ca652f3f61ed');
+----+--------------------+---------------------+------+------------------------------+----------------+---------+-------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------------------+------+------------------------------+----------------+---------+-------+----------+-------------+
| 1 | PRIMARY | search_criteria | ALL | NULL | NULL | NULL | NULL | 19582252 | Using where |
| 2 …Run Code Online (Sandbox Code Playgroud) 我的问题的小提琴可以在https://dbfiddle.uk/?rdbms=postgres_10&fiddle=3cd9335fa07565960c1837aa65143685上找到。
我有一个简单的表格布局:
class
person: belongs to a class
Run Code Online (Sandbox Code Playgroud)
我想选择所有班级,对于每个班级,我想要按降序排列的所属人员的前两个人员标识符。
我通过以下查询解决了这个问题:
select c.identifier, array_agg(p.identifier order by p.name desc) as persons
from class as c
left join lateral (
select p.identifier, p.name
from person as p
where p.class_identifier = c.identifier
order by p.name desc
limit 2
) as p
on true
group by c.identifier
order by c.identifier
Run Code Online (Sandbox Code Playgroud)
注意:我可以在SELECT子句中使用相关子查询,但作为学习过程的一部分,我试图避免这种情况。
如您所见,我order by p.name desc在两个地方申请:
有没有办法避免这种情况?我的坚持:
首先,显然我不能删除order by子查询中的 ,因为这会给出一个不符合我上述要求的查询。
其次,我认为order by聚合函数中的 不能被遗漏,因为子查询的行顺序不一定保留在聚合函数中?
我应该重写查询吗?
此查询在 ~21 秒内运行(执行计划):
select
a.month
, count(*)
from SubqueryTest a
where a.year = (select max(b.year) from SubqueryTest b)
group by a.month
Run Code Online (Sandbox Code Playgroud)
当子查询被变量替换时,它会在 <1 秒内运行(执行计划):
declare @year float
select @year = max(b.year) from SubqueryTest b
select
month
, count(*)
from SubqueryTest where year = @year group by month
Run Code Online (Sandbox Code Playgroud)
从执行计划来看,“select max...”子选择对“SubqueryTest a:”中的数百万行中的每一行都运行,这就是为什么它需要这么长时间。
我的问题:由于子选择是标量、确定性且不相关,为什么查询优化器不执行我在第二个示例中所做的操作并运行子查询一次,存储结果,然后将其用于主查询?我确定我对 SQL Server 的理解只是一个漏洞,但我真的很想帮助填补它 - 用谷歌几个小时没有帮助。
该表刚超过 1GB,有近 2800 万条记录:
CREATE TABLE SubqueryTest(
[pk_id] [int] IDENTITY(1,1) NOT NULL
, [Year] [float] NULL
, [Month] [float] NULL …Run Code Online (Sandbox Code Playgroud) 我有一个从应用程序中使用的大视图。我想我已经缩小了我的性能问题,但我不确定如何解决它。视图的简化版本如下所示:
SELECT ISNULL(SEId + '-' + PEId, '0-0') AS Id,
*,
DATEADD(minute, Duration, EventTime) AS EventEndTime
FROM (
SELECT se.SEId, pe.PEId,
COALESCE(pe.StaffName, se.StaffName) AS StaffName, -- << Problem!
COALESCE(pe.EventTime, se.EventTime) AS EventTime,
COALESCE(pe.EventType, se.EventType) AS EventType,
COALESCE(pe.Duration, se.Duration) AS Duration,
COALESCE(pe.Data, se.Data) AS Data,
COALESCE(pe.Field, se.Field) AS Field,
pe.ThisThing, se.OtherThing
FROM PE pe FULL OUTER JOIN SE se
ON pe.StaffName = se.StaffName
AND pe.Duration = se.Duration
AND pe.EventTime = se.EventTime
WHERE NOT(pe.ThisThing = 1 AND se.OtherThing = 0)
) Z …Run Code Online (Sandbox Code Playgroud) subquery ×10
mysql ×3
optimization ×3
performance ×3
postgresql ×3
order-by ×2
sql-server ×2
aggregate ×1
hibernate ×1
index ×1
innodb ×1
mysql-5.5 ×1
query ×1
sqlite ×1
t-sql ×1
union ×1
update ×1