如果您对OptimizationsforderivedtablesinMySQL5.6andMariaDB5._MySQL感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解Optimization
如果您对Optimizations for derived tables in MySQL 5.6 and MariaDB 5._MySQL感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解Optimizations for derived tables in MySQL 5.6 and MariaDB 5._MySQL的各种细节,此外还有关于100.In which situations does the Oracle Data Pump use external tables and not the direct path load w、13.3.5 LOCK TABLES and UNLOCK TABLES Statements(mysql 5.7)-内容来自官方文档、@types/tabulator-tables 打破 tabulator-tables 导入、c# – Web.Optimizations – 从风格/脚本包中获取所有内容的任何方式?的实用技巧。
本文目录一览:- Optimizations for derived tables in MySQL 5.6 and MariaDB 5._MySQL
- 100.In which situations does the Oracle Data Pump use external tables and not the direct path load w
- 13.3.5 LOCK TABLES and UNLOCK TABLES Statements(mysql 5.7)-内容来自官方文档
- @types/tabulator-tables 打破 tabulator-tables 导入
- c# – Web.Optimizations – 从风格/脚本包中获取所有内容的任何方式?
Optimizations for derived tables in MySQL 5.6 and MariaDB 5._MySQL
MariaDB
i had been involved with subquery optimizations fairly closely, but last week i was surprised to find out that mysql 5.6 does not supportderived table merging. this feature was among the subquery features in the abandoned mysql 6.0. in mariadb, it was finished and released as part ofmariadb 5.3/5.5. as for mysql, neither mysql 5.6, nor mysql 5.7 has this feature.
So what is this “derived merge”? It’s simple to understand. When one writes complex queries, it is common to use FROM-clause subqueries as a way to structure the query:
<font color="darkblue">select</font>sum(o_totalprice)<font color="darkblue">from</font>(<font color="darkblue">select</font> * <font color="darkblue">from</font> orders <font color="darkblue">where</font> o_orderpriority=’1-URGENT’) <font color="darkblue">as</font> high_prio_orders<font color="darkblue">where</font>o_orderdate <font color="darkblue">between</font> ‘1995-01-01′ <font color="darkblue">and</font> ‘1995-01-07′
MySQL optimizer processes this syntax very poorly. The basic problem is thatFROM-subqueries are always materialized exactly as-specified. Conditions from outside the subquery are applied only after the materialization.
In our example, tableordershas an index ono_orderdate, and there is a highly selective conditiono_orderdate BETWEEN ...which one can use for reading through the index. But the condition is located outside the subquery, so it will not be used when reading the table. Instead, we will get the following plan:
+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+| id | select_type | table| type | possible_keys | key| key_len | ref| rows| Extra |+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+|1 | PRIMARY | <derived2> | ALL| NULL| NULL | NULL| NULL | 1505799 | Using where ||2 | DERIVED | orders | ALL| NULL| NULL | NULL| NULL | 1505799 | Using where |+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+</derived2>
The meaning of it is:
- Do a full table scan is on table `orders`. We expect to read 1.5M rows. Write rows that matcho_orderpriority=''1-URGENT''into a temporary table
- Read the temporary table back. Filter rows that matcho_orderdate between ...and compute the query result
MySQL 5.6 has added some improvements to this (link to the manual). They are:
- The temporary table is materialized as late as possible. This has no effect of the speed of our example query, but it may have an effect for more complex queries.
- EXPLAIN also will not materialize the temporary table
- The optimizer has an option to create and use an index on the temporary table.
However, the base problem of materializing FROM subquery before applying any other optimization still remains.
In MariaDB, EXPLAIN will be different:
+------+-------------+--------+-------+---------------+---------------+---------+------+------+------------------------------------+| id | select_type | table| type| possible_keys | key | key_len | ref| rows | Extra|+------+-------------+--------+-------+---------------+---------------+---------+------+------+------------------------------------+|1 | SIMPLE| orders | range | i_o_orderdate | i_o_orderdate | 4 | NULL | 4358 | Using index condition; Using where |+------+-------------+--------+-------+---------------+---------------+---------+------+------+------------------------------------+
Note that we see only one line, and the table orders is accessed through an index ono_orderdate. RunningEXPLAIN EXTENDEDwill show why:
Message: select sum(`dbt3sf1`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3sf1`.`orders` where ((`dbt3sf1`.`orders`.`o_orderpriority` = ‘1-URGENT’) and (`dbt3sf1`.`orders`.`o_orderDATE` between ‘1995-01-01′ and ‘1995-01-07′))
There is no FROM-clause subquery anymore. It has been merged into the upper select. This allowed the optimizer to avoid doing materialization, and also to use the condition and index ono_orderdateto construct arangeaccess.
Query execution time for this particular example went down from 15 sec to 0.25 sec, but generally, the difference can be as big as your table is big.
Posted inhow-it-works,mysql,mariadbon June 30th, 2014 by spetrunia| |
100.In which situations does the Oracle Data Pump use external tables and not the direct path load w
100.In which situations does the Oracle Data Pump use external tables and not the direct path load while exporting a table? (Choose all that apply.) A.if a table is not in a cluster B.if a table has an active trigger C.if a table has an encrypted column D.if a table has a column of data type LONG defined on it E.if a table has a referential integrity constraint defined on it 答案:BCE 参考:https://docs.oracle.com/cd/B19306_01/server.102/b14215/dp_overview.htm#i1010293 The default method that Data Pump uses for loading and unloading data is direct path,when the structure of a table allows it. Note that if the table has any columns of datatype LONG,then direct path must be used.(排除D) Situations in Which Direct Path Load Is Not Used A table is in a cluster(排除A) There is an active trigger on a pre-existing table. (B正确) The table has encrypted columns(C正确) A referential integrity constraint is present on a pre-existing table.(E正确) --这里只是列出一部分,具体查看文档13.3.5 LOCK TABLES and UNLOCK TABLES Statements(mysql 5.7)-内容来自官方文档
LOCK TABLES
tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type] ...
lock_type: {
READ [LOCAL]
| [LOW_PRIORITY] WRITE
}
UNLOCK TABLES
mysql允许client session显示的获取表锁,用于访问表时,与其他session的协作,或者阻止其他session修改表。一个session获取、释放锁都是仅针对自身而言的。一个session不能获取其他session的锁,也不能释放其他session的锁。
LOCK TABLES 语句显示的为当前session获取表锁。表锁可用于表或视图。需要有LOCK TABLE权限和SELECT权限。
对于视图锁,视图用到的所有表都会自动锁住。如果你使用 LOCK TABLES 显示的锁住某个表,那么该表的触发器中用到的所有表,都会被隐式的锁住(下文有示例)。
UNLOCK TABLES 语句显示的释放当前session的所有表锁。 LOCK TABLES 语句隐式的释放当前session之前获取的锁。
UNLOCK TABLES 还用于释放由 FLUSH TABLES WITH READ LOCK (锁住所有数据库的所有表)获取的全局读锁。
表锁是为了防止其他session的不适当的读写操作。一个拥有WRITE锁的session,可以执行表级操作,如 DROP TABLE 或者 TRUNCATE TABLE ,一个拥有READ锁的session,这两个操作是不允许的。
LOCK TABLE 仅适用于non-TEMPORARY表。
Table Lock Acquisition
LOCK TABLES 用于获取表锁,通过获取metadata lock来实现。
可用的锁类型如下:
READ [LOCAL]
lock:
- 可以读取表,但是不能写。
- 多个session,可以同时获取某个表的READ锁。
- 其他没有显示的获取READ锁的session,也可以读取该表。
- LOCAL修饰符,使得在当前会话已经持有READ锁时,其他会话可以执行不冲突的插入语句(并发插入)。对于InnoDB表,READ LOCAL和READ是一样的。
[LOW_PRIORITY] WRITE
lock:
- 既可以进行读操作、也可以进行写操作。
- 仅持有锁的session可以访问表。
- 当已经有一个session持有该锁时,其他获取锁的请求会阻塞。
- LOW_PRIORITY不起作用,这是老版本的东西,现在已经弃用了,不生效了。
WRITE锁比READ锁优先级更高,这是为了确保写操作可以尽快的执行。也就是说,一个session已经获取了READ锁,另一个session请求WRITE锁,后续的READ锁请求会阻塞,直到请求WRITE锁的session获取然后又释放WRITE锁后,才会继续READ锁请求的执行(An exception to this policy can occur for small values of the max_write_lock_count system variable)。
一个需要锁的session,必须在一个 LOCK TABLES 语句中获取需要的全部锁。获取锁后,这个session仅可以访问 LOCK TABLES 语句中包含的表。例如:下面的语句中,访问 t2 会报错,因为没有在 LOCK TABLES 语句中锁住该表:
mysql> LOCK TABLES t1 READ;
mysql> SELECT COUNT(*) FROM t1;
+----------+
| COUNT(*) |
+----------+
| 3 |
+----------+
mysql> SELECT COUNT(*) FROM t2;
ERROR 1100 (HY000): Table ''t2'' was not locked with LOCK TABLES
INFORMATION_SCHEMA 数据库中的表是一个例外情况,哪怕在使用了 LOCK TABLES 语句,却未包含时,也可以访问这个数据库中的表。
如果操作某个表时使用的是别名,那么在使用 LOCK TABLES 锁表时,也必须使用相同的别名,否则会报错,示例如下:
mysql> LOCK TABLE t READ;
mysql> SELECT * FROM t AS myalias;
ERROR 1100: Table ''myalias'' was not locked with LOCK TABLES
相反的,如果 LOCK TABLES 语句使用的是别名,那么在操作此表的SQL中,也必须使用相同的别名,示例如下:
mysql> LOCK TABLE t AS myalias READ;
mysql> SELECT * FROM t;
ERROR 1100: Table ''t'' was not locked with LOCK TABLES
mysql> SELECT * FROM t AS myalias;
注意: LOCK TABLES 和 UNLOCK TABLES 语句用于分区表时,必须锁住整个表,不能仅是单独锁某个分表。
Table Lock Release
当一个session释放表锁时,该session拥有的多个表锁(如果有多个的话)同时释放。session可以显示的释放锁,也可以在某些条件下隐式的释放锁。
- 使用 UNLOCK TABLES 显示的释放表锁。
- 如果已经包含了某些锁的session,执行 LOCK TABLES 语句时,那么在新申请的锁被授权之前,现存的锁会隐式的释放掉。
- 当一个session开启一个事务(例如,使用 START TRANSACTION 语句)时,会执行一个隐式的 UNLOCK TABLES ,释放掉现存的锁。
如果一个session的连接中断,不论是正常中断还是异常中断,server会隐式的释放掉该session(事务的或非事务的)持有的所有锁。客户端重连后,之前的锁也都不在了。如果client有一个激活的事务,那么在连接断开时,server会将事务回滚,客户端重连时,session会以启用 autocommit=1 的状态开始。因为这个原因,客户端可能想要禁用auto-reconnect。当auto-reconnect禁用时,如果连接断开,那么下一条语句执行时会报错。客户端可以探测到这个错误,然后做出合适的反应,如重新获取锁,或重新开始事务。
注意:如果你对一个锁住的表,执行 ALTER TABLE 语句时,这个表会变为解锁状态。当再次执行第二次的 ALTER TABLE 时,则会报错: Table ''tbl_name'' was not locked with LOCK TABLES ,为解决此问题,在第二次的语句前,先执行锁表语句 LOCK TABLES 。
Interaction of Table Locking and Transactions
LOCK TABLES 和 UNLOCK TABLES 语句与事务的相互影响如下:
- LOCK TABLES 不是transaction-safe的,该语句在尝试锁表之前,会隐式的提交任何激活的事务。
- UNLOCK TABLES 会隐式的提交任何激活的事务,但仅在已经使用 LOCK TABLES 锁住某些表的情况下,执行该语句,才会如此。例如,在下面的语句之后,执行该语句,不会提交事务:
FLUSH TABLES WITH READ LOCK; START TRANSACTION; SELECT ... ; UNLOCK TABLES;
- 开始一个事务,例如使用 START TRANSACTION 语句,会隐式的提交任何当前事务,并释放当前存在的表锁。
- FLUSH TABLES WITH READ LOCK 获取一个全局读锁,而不是表锁,所以,不受上述影响。例如 START TRANSACTION 语句不会释放全局读锁。
- 其他的导致事务隐式提交的语句,不会释放表锁。
- 在事务型表(如InnoDB表)上正确的使用 LOCK TABLES 和 UNLOCK TABLES 的方法是:使用 SET autocommit = 0 开启事务(注意不是 START TRANSACTION ),然后使用 LOCK TABLES ,直到显示的提交事务后,调用 UNLOCK TABLES 。示例如下:
SET autocommit=0; LOCK TABLES t1 WRITE, t2 READ, ...;... do something with tables t1 and t2 here ... COMMIT; UNLOCK TABLES;
- 当调用 LOCK TABLES 时,InnoDB使用自己内部的锁,MySQL也使用自己的锁。在下一个commit时,InnoDB会释放自己内部的锁,但是要让MySQL释放锁,必须调用 UNLOCK TABLES 。不要使用 autocommit = 1 ,因为这样InnoDB会在 LOCK TABLES 语句后立即释放其内部的锁,死锁会非常容易出现。
- ROLLBACK 不会释放表锁。
LOCK TABLES and Triggers
如果使用 LOCK TABLES 进行了锁表,那么该表的触发器中用到的所有表,都被隐式的锁住:
- 这些锁,与 LOCK TABLES 获取的表锁,是同时的。
- 触发器中用到的表,要加什么锁,取决于该表是否只用于读操作。如果是,那么只加一个READ锁就够了,如果不是,那么就需要加一个WRITE锁。
- 如果一个表,显示的通过 LOCK TABLES 加了READ锁,但是如果在触发器中,该表可能会被修改,那么就会加上WRITE锁,而不是加READ锁。
下面是一个示例。
锁住两个表t1和t2:
LOCK TABLES t1 WRITE, t2 READ;
假设t1表有一个触发器,如下:
CREATE TRIGGER t1_a_ins AFTER INSERT ON t1 FOR EACH ROW
BEGIN
UPDATE t4 SET count = count+1
WHERE id = NEW.id AND EXISTS (SELECT a FROM t3);
INSERT INTO t2 VALUES(1, 2);
END;
t1和t2会被锁住,因为它们包含在了 LOCK TABLES 语句中。t3和t4也会被锁,因为触发器用到了它们。
- t1,WRITE锁。
- t2,WRITE锁,虽然在 LOCK TABLES 语句中加的是READ锁。发生这种情况是因为,触发器中尝试向t2表中插入数据,所以READ锁转换成了WRITE锁。
- t3,READ锁。因为在触发器中仅对t3进行了读取操作。
- t4,WRITE锁。因为在触发器中尝试更新t4的数据。
Table-Locking Restrictions and Conditions
你可以使用 KILL 安全的停止一个正在等待table lock的session。
LOCK TABLE 和 UNLOCK TABLES 不能用于存储程序,如存储过程,存储函数等。
performance_schema 数据库中的表不能使用 LOCK TABLES 语句进行锁定,除了 setup_xxx 表。
在 LOCK TABLES 生效时,下面的语句是被禁止执行的:CREATE TABLE、CREATE TABLE ... LIKE、CREATE VIEW、DROP VIEW、stored functions/procedures/events的DDL语句。
对于某些操作来说, mysql 库中的系统表必须是可访问的。例如, HELP 语句需要访问help tables,CONVERT_TZ()需要读取time zone tables。你不需要显示的对这些表进行锁定操作,因为在必要的情况下,server会隐式的对这些表加READ锁。例如下述的这些表:
mysql.help_category
mysql.help_keyword
mysql.help_relation
mysql.help_topic
mysql.proc
mysql.time_zone
mysql.time_zone_leap_second
mysql.time_zone_name
mysql.time_zone_transition
mysql.time_zone_transition_type
如果对这些表,你需要WRITE锁,则要使用 LOCK TABLES 语句显示的锁表。
通常的,你不需要锁表,因为所有的单个的 UPDATE 语句都是原子性的。其他的session不会妨碍语句的执行。
然而,有一些情况是需要进行锁表的:
- 如果你正在对一些 MyISAM 表进行很多操作,锁表可以使操作更快速。因为直到执行 UNLOCK TABLES 语句,MySQL不会刷新key cache。如果不锁表,那么每一条语句执行完,都会进行key cache的刷新。某些情况,锁表的也会有负面影响,因为对于加了READ锁的表,所有的session都不能对其进行更改,即使是持有锁的session也不可以进行更改;对于加了WRITE锁的表,除了持有锁的session,其他的session对此表都不可访问(读、写均不可以)。
- 如果你在使用非事务型的表,如果你想确保,在你执行SELECT和UPDATE语句之间,没有其他session会修改这个表,则必须使用 LOCK TABLES 。下面是一个示例,这个示例需要使用使用 LOCK TABLES :
LOCK TABLES trans READ, customer WRITE; SELECT SUM(value) FROM trans WHERE customer_id=some_id; UPDATE customer SET total_value=sum_from_previous_statement WHERE customer_id=some_id; UNLOCK TABLES;
大多情况下,你可以避免使用 LOCK TABLES ,通过使用相对更新( UPDATE customer SET value=value+new_value )或者 LAST_INSERT_ID() 方法。
你也可以通过如下方法来避免使用 LOCK TABLES :user-level锁方法 GET_LOCK() 和 RELEASE_LOCK() 。
- - 结束 - -
@types/tabulator-tables 打破 tabulator-tables 导入
如何解决@types/tabulator-tables 打破 tabulator-tables 导入
安装以下(从 tabulator-tables@4.9.1 开始):
npm install tabulator-tables
npm install @types/tabulator-tables
然后做下面的导入
import Tabulator from ''tabulator-tables'';
导致错误:Module Usage (Error node_modules @types tabulator tables index.d.ts'' is not a module)
。
改用这个导入
import ''tabulator-tables'';
不输出错误,并允许加载类型信息,但在运行时(例如,在 Angular 12 项目中)实际上不允许访问 Tabulator 对象,从而导致 ReferenceError: Tabulator is not defined
之类的错误。>
解决方法
这是由于 @types/tabulator-tables
中的类型定义文件中缺少默认导出。不幸的是,在上游添加默认导出是不可行的,因为它会破坏现有的代码库。
幸运的是,有一个解决方法,described here:如果您还没有创建一个 index.d.ts
文件,然后添加以下行:
declare module "tabulator-tables" { export = Tabulator; }
(还要确保通过在 index.d.ts
中列出 "files"
文件或确保它与 tsconfig.json 中的 "includes"
中的模式匹配来确保包含 "allowSyntheticDefaultImports": true
文件。您可以还需要在 "compilerOptions"
中设置 parenthesis or brackets.
。)
c# – Web.Optimizations – 从风格/脚本包中获取所有内容的任何方式?
我开了一个新的StyleBundle,这样:
var cssBundle = new StyleBundle("~/bundle/css");
然后循环通过配置并添加任何发现包括:
cssBundle.Include(config.source);
在循环之后,我想检查是否有实际包含任何文件/目录.我知道有EnumerateFiles(),但我不认为这是100%的目的.
有人做过类似的事吗?
解决方法
var cssBundle = new StyleBundle("~/bundle/css"); cssBundle.Include(config.source); // if your bundle is already in BundleTable.Bundles list,use that. Otherwise... var collection = new BundleCollection(); collection.Add(cssBundle) // get bundle contents var resolver = new BundleResolver(collection); List<string> cont = resolver.GetBundleContents("~/bundle/css").ToList();
如果你只需要一个计数:
int count = resolver.GetBundleContents("~/bundle/css").Count();
编辑:使用反射
显然我以前的反思测试做错了.
这实际上是:
using System.Reflection; using System.Web.Optimization; ... int count = ((ItemRegistry)typeof(Bundle).GetProperty("Items",BindingFlags.NonPublic | BindingFlags.Instance).GetValue(cssBundle,null)).Count;
您当然可以添加一些安全检查,并且像很多反思示例一样违反了Items属性的预期安全性,但它的工作正常.
我们今天的关于Optimizations for derived tables in MySQL 5.6 and MariaDB 5._MySQL的分享已经告一段落,感谢您的关注,如果您想了解更多关于100.In which situations does the Oracle Data Pump use external tables and not the direct path load w、13.3.5 LOCK TABLES and UNLOCK TABLES Statements(mysql 5.7)-内容来自官方文档、@types/tabulator-tables 打破 tabulator-tables 导入、c# – Web.Optimizations – 从风格/脚本包中获取所有内容的任何方式?的相关信息,请在本站查询。
本文标签: