鉴于字符串:
'我认为 PostgreSQL 很漂亮'
我想对该字符串中找到的单个单词进行操作。本质上,我有一个单独的,我可以从中获取单词详细信息,并希望在此字典上加入该字符串的未嵌套数组。
到目前为止,我有:
select word, meaning, partofspeech
from unnest(string_to_array('I think that PostgreSQL is nifty',' ')) as word
from table t
join dictionary d
on t.word = d.wordname;
Run Code Online (Sandbox Code Playgroud)
这完成了我希望做的事情的基本原理,但它没有保留原始的词序。
为什么当我们在列中有一个 NULL 值并且我们按值升序排序时,首先对 NULL 进行排序?
select 1 as test
union all
select 2
union all
select NULL
union all
select 3
union all
select 4
order by test
Run Code Online (Sandbox Code Playgroud)
结果是
NULL
1
2
3
4
Run Code Online (Sandbox Code Playgroud)
我一直认为 NULL 意味着“不确定”或可能的“未知”。如果这是真的,它们会不会排在最后,因为该值可能大于所有其他值?(或者这是某个地方的排序选项?)
我使用的是 SQL Server 2008R2,但我怀疑这适用于所有 SQL Server,并且可能适用于所有 RDBMS。
给定一个“SoftwareReleases”表:
| id | version |
| 1 | 0.9 |
| 2 | 1.0 |
| 3 | 0.9.1 |
| 4 | 1.1 |
| 5 | 0.9.9 |
| 6 | 0.9.10 |
Run Code Online (Sandbox Code Playgroud)
我如何产生这个输出?
| id | version |
| 1 | 0.9 |
| 3 | 0.9.1 |
| 5 | 0.9.9 |
| 6 | 0.9.10 |
| 2 | 1.0 |
| 4 | 1.1 |
Run Code Online (Sandbox Code Playgroud) 在我们的应用程序中,我们有一个网格,用户可以在其中翻阅大量记录(10-2000 万)。网格支持在多列 (20+) 中按升序和降序排序。许多值也不是唯一的,因此应用程序还按 id 排序作为决胜局,以确保行始终出现在同一页面上。例如,如果用户想要按小部件大小(从最大的开始)排序,应用程序会生成一个看起来像这样的查询:
SELECT TOP 30
* -- (Pretend that there is a list of columns here)
FROM Test
-- WHERE widgetSize > 100
ORDER BY
widgetSize DESC,
id ASC
Run Code Online (Sandbox Code Playgroud)
此查询需要大约 15 秒才能运行(使用缓存数据),主要成本似乎是按小部件大小对大约 130 万行进行排序。在尝试调整此查询时,我发现如果我添加一个WHERE仅限于最大 widgetSizes的子句(在上面的查询中注释掉),则查询只需要约 800 毫秒(所有前 50,000 个结果的小部件大小都大于 100) .
为什么没有WHERE子句的查询速度会如此之慢?我检查了 widgetSize 列的统计数据,它们显示前 739 行的 WidgetSize > 506。由于只需要 30 行,SQL Server 可以不使用此信息来推断它只需要对具有小部件大小的行进行排序哪个大?

我知道我可以通过在和上添加索引来使这个特定查询更快地执行,但是这个索引只在这个特定场景中有用,并且如果(例如)用户反转排序方向就变得毫无价值。该表包含许多附加列,并且每个索引都很大(~200mb),因此我无法为每个可能的排序顺序添加索引。widgetSizeid
有什么方法可以让这些查询查询执行而不为每个可能的排序顺序添加索引?(用户可以按 20 多列中的任何一列进行排序)
以下脚本创建上表并用一些代表性数据填充它。该表比实际表窄得多,但仍然展示了我所看到的性能。在我的 PC 上,带有 where 子句的查询需要约 200 毫秒,而没有 where caluse 的查询需要约 800 …
在最大内存设置为 25GB 的 SQL Server 2016 SP2 上,我们有一分钟执行大约 80 次的查询。该查询将大约 4000 页溢出到 tempdb。这会导致 tempdb 的磁盘上出现大量 IO。
当您查看查询计划(简化查询)时,您会看到估计行数等于实际行数,但仍然会发生溢出。所以过时的统计数据不能成为问题的原因。
我做了一些测试和以下查询溢出到 Tempdb:
select id --uniqueidentifier
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)
Run Code Online (Sandbox Code Playgroud)
但是,如果我选择不同的列,则不会发生溢出:
select startdate --datetime
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)
Run Code Online (Sandbox Code Playgroud)
所以我试图“放大” id 列的大小:
select CONVERT(nvarchar(512),id)
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)
Run Code Online (Sandbox Code Playgroud)
然后也不会发生溢出。
为什么 uniqueidentifier 不会溢出到 tempdb 和 datatime 列?当我删除大约 20000 条记录时,当我选择 id …
sql-server tempdb sorting sql-server-2016 cardinality-estimates
我有一个包含 720 万个元组的表,如下所示:
table public.methods
column | type | attributes
--------+-----------------------+----------------------------------------------------
id | integer | not null DEFAULT nextval('methodkey'::regclass)
hash | character varying(32) | not null
string | character varying | not null
method | character varying | not null
file | character varying | not null
type | character varying | not null
Indexes:
"methods_pkey" PRIMARY KEY, btree (id)
"methodhash" btree (hash)
Run Code Online (Sandbox Code Playgroud)
现在我想选择一些值,但查询速度非常慢:
db=# explain
select hash, string, count(method)
from methods
where hash not in
(select hash from nostring) …Run Code Online (Sandbox Code Playgroud) 我从一个示例配置文件中读取了以下内容:
# Sort buffer is used to perform sorts for some ORDER BY and GROUP BY
# queries. If sorted data does not fit into the sort buffer, a disk
# based merge sort is used instead - See the "Sort_merge_passes"
# status variable. Allocated per thread if sort is needed.
Run Code Online (Sandbox Code Playgroud)
我有几个使用文件排序的查询。如何确定查询在不碰到磁盘的情况下顺利运行所需的缓冲区大小是多少?
我有一个包含不同长度整数的 VARCHAR 列的数据库。我想对它们进行排序,所以 10 在 9 之后,而不是 1,并且 70A 在 70 之后。我可以使用WHERE 子句中的PATINDEX()、CTE 和 CASE 语句来做到这一点。
但是,我想知道是否有不需要的整理。
我有一个带有 ORDER BY 子句的查询,它使用一个列,该列是 WHERE 子句中使用的索引上的最后一列,基本上是以下形式:
SELECT
cols
FROM
tables
WHERE
col_1 = x
AND col_2 = y
AND col_3 = z
ORDER BY col_4
Run Code Online (Sandbox Code Playgroud)
并按该顺序在列(col_1、col_2、col_3、col_4)上创建索引。
当我分析查询时,超过 99% 的时间都花费在“排序结果”状态。col_4 是一个时间戳列,如果这有什么区别的话。我知道 ORDER BY 只能在某些情况下使用索引,但我仍然有点不明白优化器何时会这样做。
该表看起来像这样,它是 SCD 类型 2:
+-----------+------------------+------------------------+
| id (text) | version (serial) | created_at (timestamp) |
+-----------+------------------+------------------------+
Run Code Online (Sandbox Code Playgroud)
对于 99% 的查询,我们将搜索整个表并按附加列和连接表进行过滤。对于这些查询,我们只对每个唯一 ID 的记录的最新版本感兴趣。我们还将按created_at和其他列进行排序。
为了方便查找最新记录,我正在考虑添加一most_recent (boolean)列,如此处答案中所述:
然而我意识到我们已经有了created_at告诉我们这些信息的列 - 我们可以在搜索查询中使用 DISTINCT 子句并按创建日期排序,如 @Svet 的答案所述:
但是,我们随后必须按我们实际想要用来显示数据的列对结果重新排序。
从长远来看,添加额外的“当前”字段似乎更简单,并且性能会更高,但这也是不好的做法吗?
sorting ×10
sql-server ×4
postgresql ×3
index ×2
mysql ×2
natural-sort ×2
array ×1
collation ×1
group-by ×1
mariadb ×1
myisam ×1
order-by ×1
paging ×1
parse ×1
performance ×1
t-sql ×1
tempdb ×1
tuning ×1