我对 Oracle 11g 中的索引有一些我无法理解的问题。
我们可以创建测试数据:
create table test2(field1 varchar2(100),field2 varchar2(100),field3 number,field4 varchar2(100));
create index test2_idx1 on test2(upper(field1));
create index test2_idx1b on test2(field1);
create index test2_idx2 on test2(field3);
DECLARE
j NUMBER :=1;
BEGIN
FOR i IN 1..500000
LOOP
INSERT
INTO test2
(field1,field2, field3, field4)
VALUES
('field1='||i,'a', j, '??i' );
IF (i mod 1000)=0 THEN
j := j+1;
END IF;
END LOOP;
COMMIT;
END;
EXEC DBMS_STATS.GATHER_TABLE_STATS ('system', 'test2');
Run Code Online (Sandbox Code Playgroud)
然后我制定了一些解释计划,结果我无法理解
查询 1:
SELECT * FROM test2 WHERE field3=1;
Run Code Online (Sandbox Code Playgroud)
解释计划:

这里一切正常。使用索引。
查询 2 …
我正在使用 Oracle sqlplus。我有以下查询:
SELECT fooID from foo MINUS
SELECT fooID from bar;
Run Code Online (Sandbox Code Playgroud)
我创建了两个非聚集 B+ 树索引。一个在fooID表的字段中foo,一个在表的字段fooID中bar。之后,我分析了两个表的统计信息:foo并bar使用EXPLAIN PLAN .... 但我明白了:
SELECT STATEMENT
MINUS
SORT UNIQUE
INDEX FAST FULL SCAN FOO_INDEX
SORT UNIQUE
INDEX FAST FULL SCAN BAR_INDEX
Run Code Online (Sandbox Code Playgroud)
这怎么可能呢?做的时候INDEX FAST FULL SCAN,因为索引是 B+ 树,系统不会取回它的元组排序吗?为什么需要这样做SORT UNIQUE(数据已经排序)?
我在 Postgres 中有一个小型数据库,大约有 10,000 条记录存储公司客户。
我有一个执行非常频繁的“缓慢”执行查询(大约半秒),我的老板希望我改进它。
首先 - 我的代码:
select customer_alias.id, customer_alias.name, site.address, phone.phonenumber
from customer_alias
join customer on customer_alias.customer_id = customer.id
left join site on customer.default_site_id = site.id
left join contact_phonenumbers as phone on site.default_phonenumber = phone.id
Run Code Online (Sandbox Code Playgroud)
(编辑left join customer为join customer)
让我突然customer想到的是,即使我没有从该记录中选择任何内容,我也正在执行连接。我目前必须加入它才能获得表default_site_id的外键site。
每个客户可以有多个站点,但此列表中只能显示一个站点(必须打开一个客户才能查看所有站点)。所以我的问题是,如果我无法优化查询,是否有不同的方式可以为特定客户存储默认站点?默认电话号码也是如此
一个客户可以有多个站点,但一个站点只有一个客户(多对一)。
EXPLAIN 返回:
Hash Join (cost=522.72..943.76 rows=5018 width=53)
Hash Cond: (customer.id = customer_alias.customer_id)
-> Hash Right Join (cost=371.81..698.77 rows=5018 width=32)
Hash Cond: (site.id = customer.default_site_id) …Run Code Online (Sandbox Code Playgroud) 我有 2 种不同的方式来查询在执行时表现出性能差异的内容。第一种方法是
EXPLAIN select SOME_COLUMNS
from
( select *
from A
where CONDITION
) p
inner join
( select *
from B
)st
on p.id = st.id;
Run Code Online (Sandbox Code Playgroud)
此查询的输出返回:
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "Extra"
1 PRIMARY derived3 ALL NULL NULL NULL NULL 25607 " "
1 PRIMARY derived2 ALL NULL NULL NULL NULL 21037 Using where; Using join buffer
3 DERIVED A ALL NULL NULL NULL NULL 23202 " "
2 DERIVED B ref IDX_A_TYPE_ID …Run Code Online (Sandbox Code Playgroud) 对于以下查询
SELECT MAX(CONCAT(date, ' ', last_entry)) AS LAST_LOG
FROM entry_log
WHERE TRIM(LEADING 0 FROM card_no)='2948'
Run Code Online (Sandbox Code Playgroud)
我已经索引了
date
card_no
date,last_entry
date,last_entry,card_no
Run Code Online (Sandbox Code Playgroud)
我的解释显示
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE entry_log index NULL date_last_card 158 NULL 103766 Using where; Using index
Run Code Online (Sandbox Code Playgroud)
我的解释扩展节目
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE entry_log index NULL date_last_card 158 NULL 103766 100.00 Using where; Using index
Run Code Online (Sandbox Code Playgroud)
我想知道我可以删除/使用哪个索引,我的路径是否正确,我应该如何提高上述查询的执行时间?
CREATE TABLE `entry_log` (
`id` int(11) NOT NULL AUTO_INCREMENT, …Run Code Online (Sandbox Code Playgroud) 我有一个看起来像这样的查询:
SELECT post.id, post.author_id, post.published_at, post.content
FROM post
WHERE post.group_id = 1
ORDER BY post.published_at DESC, post.id
LIMIT 5;
Run Code Online (Sandbox Code Playgroud)
(group_id, published_at DESC, id)当没有使用行级别安全性 (RLS) 策略时,此查询具有一个索引,该索引为其提供此查询计划。
Limit (cost=0.14..1.12 rows=5 width=143)
-> Index Scan using post_published_at on post (cost=0.14..15.86 rows=80 width=143)
Index Cond: (group_id = 1)
Run Code Online (Sandbox Code Playgroud)
然后我添加这个策略:
CREATE POLICY select_member_of ON post FOR SELECT USING
(EXISTS (SELECT 1
FROM group_member
WHERE group_member.account_id = current_setting('current_account_id', false)::INT AND
group_member.group_id = post.group_id));
Run Code Online (Sandbox Code Playgroud)
有在化合物主键group_member.account_id和group_member.group_id上group_member表中。
我希望Postgres的计划此查询为仅索引扫描的group_member,因为这两个group_member.account_id和 …
postgresql performance execution-plan row-level-security explain query-performance
我有一个大约有 3000 万行的表(很快就会增加两倍/三倍),我必须在其中进行定期更新。表结构如下:
id,
cookie_id VARCHAR(45),
country VARCHAR(45),
category VARCHAR(45),
other_non_relevant_columns
Run Code Online (Sandbox Code Playgroud)
索引看起来像这样:
SHOW INDEX FROM data;
+-------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| data | 0 | PRIMARY | 1 | id | A | 24767570 | NULL | NULL | | BTREE | | |
| data | 1 | cookie_index | 1 | cookie_id | …Run Code Online (Sandbox Code Playgroud) mysql performance delete explain mysql-5.7 query-performance
是否有一些技巧可以让可视化解释功能在 MySQL Workbench 中工作?
我在 Windows 7 上运行版本 6.3.6。我尝试过仅使用一个连接进行简单查询。我已经尝试过使用 12 个连接的复杂查询。我已经用 MySQL 5.5 和 5.7 尝试过。
但每次我刚刚得到Explain Data Not Available For Statement
我查看了 MySQL Workbench 的 Bugs > Visual Understanding,但没有最近的 bug,这让我认为这是我正在做的事情。但我看不到什么。有人有一些建议吗?
我有一个表(postgres 9.6),它按日期划分为大约 70 个子表。
EXPLAIN下面的输出被截断,因为它的大部分是每个子表的相同位图索引/堆扫描(这里是完整的详细输出)。我感兴趣的部分是树顶部附近的Append和Result节点。
Append只是所有子查询的总和。事实上,它需要比这长约 3.5 秒。多余的从哪里来?Resultwhich states当您的查询选择某个常量值时,将使用此操作。此节点大约需要 7 秒,但查询未选择常量值。如果可能的话,我很想节省这 10 秒,但我实际上并不知道这些节点在做什么,所以我不知道该尝试什么。
EXPLAIN ANALYZE 输出:
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? QUERY PLAN ?
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? HashAggregate (cost=4459946.40..4473566.96 rows=1089645 width=64) (actual time=26289.308..26419.989 rows=190112 loops=1) ?
? Group Key: frontend_prescription.processing_date, frontend_prescription.pct_id, substr((frontend_prescription.presentation_code)::text, 1, 9) ?
? Buffers: shared hit=172527 ?
? -> Result (cost=0.00..4296499.68 rows=10896448 width=60) …Run Code Online (Sandbox Code Playgroud) 我正在尝试调查为什么此查询的性能如此不确定。它可能需要 1 秒到 60 秒及以上的任何时间。查询的本质是选择一个“时间窗口”,并从该时间窗口内获取所有行。
这是有问题的查询,在大约 10 亿行的表上运行:
SELECT CAST(extract(EPOCH from ts)*1000000 as bigint) as ts
, ticks
, quantity
, side
FROM order_book
WHERE ts >= TO_TIMESTAMP(1618882633073383/1000000.0)
AND ts < TO_TIMESTAMP(1618969033073383/1000000.0)
AND zx_prod_id = 0
ORDER BY ts ASC, del desc;
Run Code Online (Sandbox Code Playgroud)
这就是表的创建方式
CREATE TABLE public.order_book
(
ts timestamp with time zone NOT NULL,
zx_prod_id smallint NOT NULL,
ticks integer NOT NULL,
quantity integer NOT NULL,
side boolean NOT NULL,
del boolean NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
TO_TIMESTAMP当我走整张桌子时,其中的值将继续向前滑动。以下是EXPLAIN ANALYZE两个不同时间窗口上相同查询的输出: …
explain ×10
mysql ×4
postgresql ×4
performance ×3
index ×2
cache ×1
delete ×1
index-tuning ×1
join ×1
mysql-5.7 ×1
optimization ×1
oracle ×1
oracle-11g ×1
pgadmin ×1
sorting ×1
sqlplus ×1
timescaledb ×1