- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我创建了一个名为“myview”的 View ,如下所示。
create view myview
as select 'a' source,col1,col2
from table_a
union
select source,col1,col2
from table_b
;
table_a
在 col1
上有一个索引,table_b
在 source
上有一个索引,col1
。当我如下查询 myview
时,没有使用索引。
select *
from myview
where source = a
and col1 = 'xxx'
;
如何让索引在这个查询上起作用?
CREATE TABLE `table_a` (
`col1` VARCHAR(50) NULL DEFAULT NULL,
`col2` VARCHAR(50) NULL DEFAULT NULL,
INDEX `table_a_idx01` (`col1`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
;
CREATE TABLE `table_b` (
`source` VARCHAR(50) NULL DEFAULT NULL,
`col1` VARCHAR(50) NULL DEFAULT NULL,
`col2` VARCHAR(50) NULL DEFAULT NULL,
INDEX `table_b_idx01` (`source`, `col1`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
;
create view myview
as select 'a' source,col1,col2
from table_a
union
select source,col1,col2
from table_b
INSERT INTO table_a (col1, col2)
VALUES
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2');
INSERT INTO table_b (source,col1, col2)
VALUES
('b','test2', 'testcol2'),
('b','test2', 'testcol2'),
('b','test2', 'testcol2'),
('b','test2', 'testcol2'),
('b','test2', 'testcol2'),
('b','test2', 'testcol2');
explain
select *
from table_a
where col1 = 'test'
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,table_a,ref,table_a_idx01,table_a_idx01,153,const,5,Using index condition
explain
select *
from table_b
where source = 'b'
and col1 = 'test'
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,table_b,ref,table_b_idx01,table_b_idx01,306,const,const,1,Using index condition
explain
select *
from myview
where source = 'b'
and col1 = 'test'
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,PRIMARY,<derived2>,ref,<auto_key0>,<auto_key0>,306,const,const,1,Using where
2,DERIVED,table_a,ALL,\N,\N,\N,\N,6,\N
3,UNION,table_b,ALL,\N,\N,\N,\N,6,\N
\N,UNION RESULT,<union2,3>,ALL,\N,\N,\N,\N,\N,Using temporary
最佳答案
您不能在 View 上创建索引:http://dev.mysql.com/doc/refman/5.7/en/view-restrictions.html ,所以你必须希望索引被使用。 https://stackoverflow.com/a/7922711/3595565
解决方法
文档另一部分的评论中提到了一个解决方法:https://dev.mysql.com/doc/refman/5.5/en/create-view.html您可以在其中创建一个常规表并设置您的专用索引并将数据从 View 加载到表中。
Creating a materialized view emulation as described above looks good, the only problem is that we are inheriting the lack of indexes MySQL views expose.
My solution is to create a correctly indexed table according to my needs, having the exact same structure as the view, and then running something like this:
LOCK TABLES materializedView WRITE;
TRUNCATE materializedView;
INSERT INTO materializedView SELECT * FROM regularView;
UNLOCK TABLES;
That way all indexes from materializedView are preserved on every "refresh".
I'm planning to use this in an application I'm doing right now, where we will have a lot more SELECTs than inserts/updates. If I keep a regular view for my SELECTs, I'll be asking the server to make tons of calculations every time someone needs to know how many items are on stock for product "A", instead, I'll have all SELECTs towards the "materializedView" with correct SKU, Store and Period indexes.
The view "refresh" will occur every time someone runs an INSERT or UPDATE, which will be on a 20 to 1 ratio. (20 Selects for every Update or Insert)
I hope things go as smooth as I'm planning. Greetings ;-)
为什么您的查询不使用索引?
当在 SELECT
中使用 UNION
时,mysql 会创建一个临时表来保存数据。因此,由于 View 是更复杂查询的“快捷方式”,因此在调用选择时,它将再次执行联合,使用临时表......使用 temptable alghorithm 来处理数据。
再次查看手册:http://dev.mysql.com/doc/refman/5.7/en/view-restrictions.html
Indexes can be used for views processed using the merge algorithm. However, a view that is processed with the temptable algorithm is unable to take advantage of indexes on its underlying tables (although indexes can be used during generation of the temporary tables).
结论:查询中的 UNION
阻碍了 View 使用索引。
来源
question in mysql forum for the same problem回答:
I guess the union causes the view to use the temptable algorithm, it creates a temporary table and then apply the where condition to the temporary table.
bugreport "DO NOT CREATE TEMPORARY TABLES FOR UNION ALL"
Currently, union queries always use a temporary table to store the result before it is returned to the user. [...]
已在 MySQL 5.7 中修复 http://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-3.html
The server no longer uses a temporary table for UNION statements that meet certain qualifications. Instead, it retains from temporary table creation only the data structures necessary to perform result column typecasting.[...]
一些用于检查分析器的测试数据
CREATE TABLE test1 (
id int auto_increment PRIMARY KEY,
col1 varchar(50),
col2 varchar(50)
);
CREATE TABLE test2 (
id int auto_increment PRIMARY KEY,
col1 varchar(50),
col2 varchar(50)
);
INSERT INTO test1 (col1, col2)
VALUES
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2');
INSERT INTO test2 (col1, col2)
VALUES
('test2', 'testcol2'),
('test2', 'testcol2'),
('test2', 'testcol2'),
('test2', 'testcol2'),
('test2', 'testcol2'),
('test2', 'testcol2');
CREATE VIEW testview AS
SELECT * FROM test1
UNION
SELECT * FROM test2;
检查分析器:
SET PROFILING = 1;
SELECT * FROM testview WHERE id = 1;
+----+-------+----------+
| id | col1 | col2 |
+----+-------+----------+
| 1 | test | testcol2 |
| 1 | test2 | testcol2 |
+----+-------+----------+
SHOW PROFILE;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000017 |
| Waiting for query cache lock | 0.000004 |
| checking query cache for query | 0.000029 |
| checking permissions | 0.000006 |
| Opening tables | 0.000121 |
| System lock | 0.000012 |
| checking permissions | 0.000014 |
| checking permissions | 0.000032 |
| optimizing | 0.000004 |
| statistics | 0.000007 |
| preparing | 0.000006 |
| executing | 0.000003 |
| Sending data | 0.000046 |
| optimizing | 0.000003 |
| statistics | 0.000004 |
| preparing | 0.000003 |
| executing | 0.000002 |
| Sending data | 0.000023 |
| optimizing | 0.000003 |
| statistics | 0.000003 |
| preparing | 0.000003 |
| executing | 0.000002 |
| Sending data | 0.000008 |
| removing tmp table | 0.000005 |
| Sending data | 0.000005 |
| Waiting for query cache lock | 0.000002 |
| Sending data | 0.000024 |
| init | 0.000011 |
| optimizing | 0.000006 |
| statistics | 0.000004 |
| preparing | 0.000006 |
| executing | 0.000002 |
| Sending data | 0.000021 |
| end | 0.000003 |
| query end | 0.000004 |
| closing tables | 0.000002 |
| removing tmp table | 0.000004 |
| closing tables | 0.000006 |
| freeing items | 0.000005 |
| Waiting for query cache lock | 0.000003 |
| freeing items | 0.000013 |
| Waiting for query cache lock | 0.000002 |
| freeing items | 0.000002 |
| storing result in query cache | 0.000003 |
| logging slow query | 0.000002 |
| cleaning up | 0.000003 |
+--------------------------------+----------+
我不能从配置文件中提取太多信息,但它确实提到了临时表,足以(对我而言)验证我的结论。
关于 View 上的 Mysql 索引不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38391726/
这几天我一直在努力。我一直在自学 CSS,所以对菜鸟好一点。我正在创建一个推荐 slider 。推荐以 3 个 block 显示。我希望前 2 个下降,第 3 个上升。但是当 slider 激活时,无
我最近开始学习 Nodejs,现在我很困惑我的网络应用程序使用什么,html 还是 ejs (Express)。 Ejs 使用 Express 模块,而 .html 使用 HTML 模块。我的第一个问
假设我们有一个 PostgreSQL 表contacts,每条记录都有一堆带标签的电子邮件地址(标签和电子邮件对)——其中一个是“主要”。 存储方式如下: id 主键 电子邮件 文本 email_la
我成功为一种新的tesseract语言编写了traineddata文件,但是当我完成时,我继续收到以下错误: index >= 0 && index = 0 && 索引 < size_used_ :E
这个问题已经有答案了: How to deal with SettingWithCopyWarning in Pandas (21 个回答) 已关闭 4 年前。 假设我有一个像这样的数据框,第一列“密
如果我有一个位置或行/列同时用于 A 和 B 位置,请检查 B 是否与 A 成对角线? 1 2 3 4 5 6 7 8 9 例如,我如何检查 5 是否与 7 成对角线? 此外,如果我检查 4 是
MongoDB:索引 一、 创建索引 默认情况下,集合中的_id字段就是索引,我们可以通过getIndexes()方法来查看一个集合中的索引 > db.user.getIndexes() [ { "v
一、索引介绍 索引是一种用来快速查询数据的数据结构。 B+Tree就是一种常用的数据库索引数据结构,MongoDB采用B+Tree 做索引,索引创建在colletions上。 MongoDB不使用索引
我无法决定索引。 就像我有下面的查询需要太多时间来执行: select count(rn.NODE_ID) as Count, rnl.[ISO_COUNTRY_CODE] as Cou
我有这些表: CREATE TABLE `cstat` ( `id_cstat` bigint(20) NOT NULL, `lang_code` varchar(3) NOT NULL,
我正在尝试找到一种方法来提高包含 IP 范围的 mysql 表的性能(在高峰时段每秒最多有 500 个 SELECT 查询(!),所以我有点担心)。 我有一个这种结构的表: id smallint(
jquery index() 似乎无法识别元素之一,总是说“无法读取未定义的属性‘长度’”这是我的代码。mnumber 是导致问题的原因。我需要 number 和 mnumber 才能跟踪使用鼠标,并
我们有一个包含近 4000 万条记录的 MongoDB 集合。该集合的当前大小为 5GB。此集合中存储的数据包含以下字段: _id: "MongoDB id" userid: "user id" (i
文档说:如果你有多个字段的复合索引,你可以用它来查询字段的开始子集。所以如果你有一个索引一个,乙,丙你可以用它查询一种一个,乙a,b,c 我的问题是,如果我有一个像这样的复合索引一个,乙,丙我可以查询
我正在使用 $('#list option').each(function(){ //do stuff }); 循环列表中的选项。我想知道如何获取当前循环的索引? 因为我不想让 var i = 0;循
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL
SQLite 索引(Index) 索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书后边的索引是非常相似的。
我是 RavenDB 的新手。我正在尝试使用多 map 索引功能,但我不确定这是否是解决我的问题的最佳方法。所以我有三个文件:Unit、Car、People。 汽车文件看起来像这样: { Id: "
我有以下数据,我想根据范围在另一个表中建立索引 我想要实现的是,例如,如果三星的销售额为 2500,则折扣为 2%,低于 3000 且高于 1000 我知道它可以通过索引来完成,与多个数组匹配,然后指
我正在检查并删除 SQL 数据库中的重复和冗余索引。 所以如果我有两个相同的索引,我会删除。 例如,如果我删除了重叠的索引... 索引1:品牌、型号 指标二:品牌、型号、价格 我删除索引 1。 相同顺
我是一名优秀的程序员,十分优秀!