表jtest有 200k 行,每行包含 jsonb { id: "<uuid>", key: <index> }(<index>每行递增 1-200k 的整数)。上还有btree索引data->'key'。
create extension if not exists pgcrypto;
create table jtest (data jsonb not null default '{}');
insert into jtest (data)
select json_build_object('id', gen_random_uuid(), 'key', i)::jsonb
FROM generate_series(1,200000) i;
create index jtest_key on jtest ((data->'key'));
Run Code Online (Sandbox Code Playgroud)
第一个查询(快速):
EXPLAIN ANALYZE
select j.data
from jtest j
order by j.data->'key'
limit 20;
-- "Limit (cost=0.42..1.43 rows=20 width=74) (actual time=0.023..0.044 rows=20 loops=1)"
-- " -> Index Scan using …Run Code Online (Sandbox Code Playgroud) 我有一个 1:m 协会。
symbols表中有很多行company_key_statistics。company_key_statistics有一个时间戳列createdAt,指示行的创建时间。我需要加入最新symbols的company_key_statistics,但我只需要最新的company_key_statistics。例如,我需要获取ORCL并且MSFT symbols仅获取他们最新的company_key_statistics.
到目前为止我已经尝试过了。
SELECT `symbols`.`id`,
`symbols`.`symbol`,
`statistics`.
`marketCapitalization`
FROM `symbols`
LEFT JOIN (SELECT `s`.`companyId`,
`s`.`marketCapitalization`
FROM `company_key_statistics` AS `s`
WHERE `s`.`companyId` = `symbols`.`id`
ORDER by `createdAt`
DESC LIMIT 1) AS `statistics`
ON `symbols`.`id` = `statistics`.`companyId`
WHERE `symbols`.`symbol` IN ('ORCL', 'SNAP');
Run Code Online (Sandbox Code Playgroud)
但不幸的是我发现我不能在子查询中使用父查询中的列JOIN。
我怎样才能做到这一点?
Microsoft SQL Server 通过sp-getapplock命令和相关命令提供任意应用程序定义的锁定机制。
键, or resource_name,被指定为一个字符串,一个 varchar 255。但文档还提到键/名称是散列的。
所以这让我想知道:
我正在为特殊需求应用程序的许多表的行实施悲观锁定机制。作为我的应用锁键/名称,我计划使用一个代表每个表的数字与存储在每一行中的 ID 号相结合。示例键/名称可能类似于mydb_myschema_table0000000142_row0000241738. 我可能一次有许多活动,所以我需要了解这些限制。
我有下表:
CREATE TABLE dpg2
(
account_id integer NOT NULL,
tank_id integer NOT NULL,
battles integer,
dmg integer,
frags integer,
wins integer,
recent_battles integer[],
recent_dmg integer[],
recent_frags integer[],
recent_wins integer[],
dpg real,
recent_ts timestamp with time zone[],
recent_dpg real,
CONSTRAINT dpg2_pkey PRIMARY KEY (account_id, tank_id)
)
Run Code Online (Sandbox Code Playgroud)
使用此索引:
CREATE INDEX dpg_tank_id_idx
ON dpg2
USING btree
(tank_id, dpg DESC NULLS LAST);
Run Code Online (Sandbox Code Playgroud)
我运行了以下查询:
explain analyze
select dpg2.account_id, tank_id, (select nickname from players2 where players2.account_id = dpg2.account_id), dpg2.battles, dpg,
frags*1.0/dpg2.battles, wins*100.0/dpg2.battles, dpg2.recent_dpg
from dpg2
where …Run Code Online (Sandbox Code Playgroud) 我有一个如下所示的查询:
Select t1.field1, t2.field2, sum(t1.field3)
From t1 inner join t2 on t1.id = t2.id
Group by t1.field1, t2.field2
Run Code Online (Sandbox Code Playgroud)
它被简化了,通常上面有更多的连接和属性。我现在的问题是,将 TOP N 子句添加到查询而不是在 N 行返回到我的 C# 代码后停止查询的影响有多大。
我知道,添加该条款对服务器更好,但我对粗略估计该条款有多大影响很感兴趣。我的猜测是,因为我有一个聚合,服务器无论如何都必须处理所有行,因此影响不是那么大。
编辑:C# Snippet 我们如何停止执行
var cmd = new SqlCommand();
cmd.CommandText = sqlStatement;
cmd.Connection = connectionString;
SqlDataReader dr;
dr = cmd.ExecuteReader();
while (dr.HasRows)
{
while (dr.Read())
{
MyDataRow newRow = new MyDataRowDataRow();
newRow.Parse(dr); //Parse the value from datarow to our format
result.Add(newRow);
if (topN.HasValue)
{
if (result.Count >= topN.Value)
{
break; //stop reading!
}
} …Run Code Online (Sandbox Code Playgroud) 由于 MySql 不支持子查询中的主别名引用,因此创建具有多行的查询有点困难,您必须限制左连接表的行。
让我们概述一下简单的例子。
假设有两个表:
CREATE TABLE `items` (
`id` INT NOT NULL AUTO_INCREMENT,
`parent` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE `sub_items` (
`id` INT NOT NULL AUTO_INCREMENT,
`child` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL,
`parent_id` INT NOT NULL,
PRIMARY KEY (`id`));
Run Code Online (Sandbox Code Playgroud)
内容如下:
INSERT INTO `items` (`parent`) VALUES ('Main item1');
INSERT INTO `items` (`parent`) VALUES ('Main item2');
INSERT INTO `items` (`parent`) VALUES ('Main item3');
INSERT INTO `sub_items` (`child`, `parent_id`) VALUES ('Child …Run Code Online (Sandbox Code Playgroud) 我有一个返回所需输出的查询。
SELECT
shop,
JSON_AGG(item_history.* ORDER BY created_date DESC) as data
FROM item_history
GROUP BY
shop;
Run Code Online (Sandbox Code Playgroud)
结果:
[
{
"shop": "shop1",
"data": [
{
"id": 226,
"price": "0",
"shop": "shop1.com",
"country": "UK",
"item": "item1",
"created_date": "2021-06-07T08:48:42.338201",
},
{
"id": 224,
"price": "0",
"shop": "shop1.com",
"country": "UK",
"item": "item 1",
"created_date": "2021-06-07T07:53:25.030621",
},
...
},
{
"shop": "shop2",
"data": [
{
"id": 225,
"price": "0",
"shop": "shop2.com",
"country": "DE",
"item": "Item 2",
"created_date": "2021-06-07T08:48:36.443849",
},
...
]
Run Code Online (Sandbox Code Playgroud)
这正是我想要的输出,但问题是它获取data数组下的所有项目,最好限制该数组。我尝试添加LIMIT
SELECT …Run Code Online (Sandbox Code Playgroud) 简单查询:
select sum(score) total,name,gender,dob,country
from users join scores on users.id = scores.user_id
where date between '2012-01-01' and '2012-01-31 23:59:59'
group by scores.user_id having sum(score)>=1000 order by sum(score) desc limit 50
Run Code Online (Sandbox Code Playgroud)
因此,尝试获取 2012 年 1 月的累积分数列表,按分数降序排列它们并对其进行分页。
无限制:缓慢但可以:搜索 69348 行。(很高兴弄清楚如何避免临时表,但我不能)。解释说:
1, 'SIMPLE', 'scores', 'range', 'user,date,user+date', 'date', '8', '', 69348, 'Using where; Using temporary; Using filesort'
1, 'SIMPLE', 'users', 'eq_ref', 'PRIMARY', 'PRIMARY', '8', 'scores.user_id', 1, 'Using where'
Run Code Online (Sandbox Code Playgroud)
有限制:它是一样的,但行搜索现在是 1806794,它需要永远。
如果有任何区别,它是一个分区的 InnoDB,所有数据都在一个分区上。
我们有一个应用程序,它使用 MSSync 将数据从服务器下载到客户端的 SQL Server Express 2005。客户端具有双核和超线程,因此总共有 4 个核。
我对 SQL Server Express 的局限性进行了大量研究,我认为它归结为 1 个物理套接字,但在该套接字中最多使用 4 个内核。但是,这提出了一些与我在实践中所感知到的形成对比的问题。
我们的同步过程将 1 个内核最大化,淹没了同步过程,导致性能比具有更高 GHz 且未最大化 SQL Server Express 2005 使用的单个内核的设备慢 10-20 倍。
但是:如果允许 SQL Server 在 1 个套接字中使用 4 个内核,为什么它只使用 1 个用于我们的同步过程?这是因为 1 个连接有一个专用核心吗?还是我没有正确理解限制规格?将 SQL Server Express 升级到现代版本是否有助于让它使用更多内核?
我做了更多的研究。我使用了 SQL Server Express 2012 甚至 SQL Server Developer 2012 并且 ALL 最多只有 1 个核心。因此,显然,这与 Express 限制无关。
这可能是一个技术限制,您在单个连接/事务中的查询仅停留在单个核心上。很可能,这是保证事务一致性的逻辑要求。
我在 SQL Server 2012 中看到的是,负载会时不时地交换到另一个核心,但它永远不会同时使用超过 1 个核心。甚至没有开发版。
如果有人能证实这些假设,那将是受欢迎的。
sql-server-2005 sql-server sql-server-2012 sql-server-express limits
如果我有一张桌子User,做这样的事情会更快:
SELECT * FROM user WHERE id > ? ORDER BY id LIMIT 10000
(每个后续查询都使用前最后一行的 id 作为参数)
或者使用带有偏移量的 LIMIT,如下所示:
SELECT * FROM user ORDER BY id LIMIT ?, 10000
(到目前为止检索到的记录总数是偏移量)。
作为一个额外的复杂因素,如果我想基于链接表连接执行类似的查询怎么办?就像说一个user可以属于多个角色,所以我想要一个查询
SELECT u.*
FROM user u
INNER JOIN user_roles ur ON ur.user_id = u.id
WHERE ur.role_name IN ('Admin', 'SuperUser', 'etc.')
LIMIT ?, 10000
连接是否会影响关于首选哪种样式查询的决定?
limits ×10
mysql ×4
group-by ×3
postgresql ×3
optimization ×2
order-by ×2
sql-server ×2
subquery ×2
join ×1
locking ×1
mysql-5.6 ×1
offset-fetch ×1
paging ×1
performance ×1
sorting ×1