我喜欢 InnoDB 的安全性、一致性和自检性。
但我需要 MyISAM 的速度和轻量级。
我怎样才能使 MyISAM 不太容易因崩溃、错误数据等而损坏?通过检查(检查表或myisamchk)需要很长时间。
我不是在要求事务安全——这就是 InnoDB 的用途。但我确实想要一个可以快速重启而不是几小时(或几天!)之后的数据库。
更新:我不是在问如何更快地将数据加载到表中。我已经对此表示反对,并确定将 MyISAM 表用于我的 LOAD DATA 会快得多。我现在所追求的是降低使用 MyISAM 表的风险。也就是说,减少损坏的机会,提高恢复速度。
我注意到我们的 MySQL 服务器上的“显示进程列表”表示许多线程处于“系统锁定”状态,通常后面只是“锁定”,后者是我所期望的,因为我们有一些选择锁定在更新/插入后面一个 MyISAM 表。
但是“系统锁定”显示的不仅仅是“锁定”(根据探查器,有时简单的选择会增加长达 2 秒的时间),而且我不明白它表示什么。我在网上找不到太多关于系统锁的信息,但那里主要讨论多个 mysqld 访问同一个数据库的情况,这不是我的情况。此外,我的“跳过外部锁定”变量是错误的。
有人有这方面的经验吗?
附录:
如果有帮助的话,我倾向于在进程列表中看到更多的系统锁比表锁(“锁定”)多,大约为 3 比 1。是否有可能由于某种原因输出“系统锁”以实现有效的常规表锁定?
我们有哪些行获得插入只有表底部的大MyISAM表.
在做一些基准测试时,我意识到选择不会(总是)将其他插入锁定到同一个表中.但是,当插入来自存储过程/函数时,它们将被select锁定.
这是为什么?
要演示此行为:
CREATE TABLE Foo (
ID INT NOT NULL AUTO_INCREMENT,
Bar VARCHAR(200),
PRIMARY KEY(ID)) ENGINE=MyISAM;
--INSERT into Foo 10M rows
DELIMITER $$
DROP PROCEDURE IF EXISTS InsertProc$$
CREATE PROCEDURE InsertProc(IN vBar VARCHAR(255))
BEGIN
INSERT Foo(Bar) VALUES (vBar);
END$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
运行以下查询:
SELECT Count(*) FROM Foo WHERE INSTR(Bar, 'abcdefg') > 0;
Run Code Online (Sandbox Code Playgroud)
当Select正在运行时,打开一个新连接并运行以下插入查询:
INSERT Foo(Bar) VALUES ('xyz1234');
Run Code Online (Sandbox Code Playgroud)
该Insert将立即运行并返回,但是,如果我运行以下查询:
CALL InsertProc('xyz1234');
Run Code Online (Sandbox Code Playgroud)
现在查询将锁定并等待select完成.
在Window Server 2K3上运行的MySql版本:5.0.51
谢谢.
- 更新这是配置文件输出:
直接插入:
(initialization) 0.0000432
checking permissions 0.0000074
Opening tables 0.0000077
System lock 0.0000032 …Run Code Online (Sandbox Code Playgroud) 我有一个MySQL表将url存储为唯一键.我开始在我的键上发生冲突,因为看起来键本身只是前任64个字节(或者你喜欢的字符,它是latin-1整理的)任何url.因此,如果一个网址超过64个字符,并且我已经有一个类似的网址,则会抛出错误.
例如:
SELECT l.link_id FROM mydb.links l WHERE
url = 'http://etonline.com/tv/108475_Charlie_Sheen_The_People_Have_Elected_Me_as_Their_Leader/index.html'
Run Code Online (Sandbox Code Playgroud)
抛出此错误:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
'http://etonline.com/tv/108475_Charlie_Sheen_The_People_Have_Elec' for key 'url'
Run Code Online (Sandbox Code Playgroud)
Isnt MyISAM应该有1000字节的密钥长度吗?
编辑:在CREATE TABLE STATUS调用中似乎没有列出前缀长度,它看起来像这样:
CREATE TABLE `links` (
`link_id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(500) NOT NULL,
PRIMARY KEY (`link_id`),
UNIQUE KEY `url` (`url`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)
我尝试在256处设置一个像这样:
ALTER TABLE `mydb`.`links`
DROP INDEX `url`, ADD UNIQUE INDEX `url` (`url`(256) ASC) ;
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
ERROR 1062: Duplicate entry '<...64-byte key...>' for key 'url'
SQL Statement:
ALTER TABLE …Run Code Online (Sandbox Code Playgroud) 我正在尝试优化一个简单的SQL查询,该查询将在很多次数据上运行.
这是场景:
一个真实的查询:
SELECT one_field, another_field
FROM big_table
INNER JOIN medium_table ON ( ... )
INNER JOIN small_table ON ( ... )
WHERE week >= #number AND week <= #number AND year >= #number AND year <= #number
AND medium_table.indexed_field = #number
AND small_table.pk= #number
Run Code Online (Sandbox Code Playgroud)
一些测试结果:
如何改进查询或数据库方案?
最好连接我的年/周字段和[yearweek]索引字段?
在一些基准测试中,我看到MyISAM比Innodb更快,但似乎我有一点改进:
http://www.mysqlperformanceblog.com/files/benchmarks/innodb-myisam-falcon.html
http://www.jortk.nl/2008/12/mysql-performance-benchmark-myisam-versus-innodb/
Run Code Online (Sandbox Code Playgroud)
是否值得失去FK并前往MyISAM?
谢谢!
更新:
解释选择:
1 SIMPLE small_table const PRIMARY PRIMARY 4 const 1 Using index
1 SIMPLE medium_table index_merge PRIMARY,Fk_small_table, …Run Code Online (Sandbox Code Playgroud) 我有一个带有全文索引的 MySql MyISAM 表,如下所示:
CREATE TABLE `tblsearch` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`brand` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `index_all` (`title`,`brand`)
) ENGINE=MyISAM AUTO_INCREMENT=1316109 DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
现在我需要编写这样的查询来查找具有确切标题和品牌的所有条目:
SELECT id FROM tblsearch WHERE title=?title AND brand=?brand;
Run Code Online (Sandbox Code Playgroud)
重要的是查询只提供完全匹配。我希望能够使用我已有的全文索引。是否可以编写查询以便使用全文索引?
最近几天,我的网站有时变得非常慢。我开始尽我所能进行调查。我看到 MySQL 进程使用了服务器可用内存的 85 - 95%(我也应该升级内存吗?)。
我检查了 MySQL 进程日志,发现有大量查询:
等待表级锁
但我还注意到,所有这些带有“表级锁”的查询都只是与我的表有关的查询users。
我还有 20 个其他表,不断有查询,但我没有在列表中看到它们。所以我猜问题出在 users 表上?
我想知道如何改进表,并最终删除表级锁?
我也运行了这个:
SHOW VARIABLES LIKE 'query_cache%';
Run Code Online (Sandbox Code Playgroud)
结果是这样的:
query_cache_limit
1048576
query_cache_min_res_unit
4096
query_cache_size
33554432
query_cache_type
ON
query_cache_wlock_invalidate
OFF
Run Code Online (Sandbox Code Playgroud)
请让我知道我可以做些什么来改进我的数据库/mysql。
这是进程列表:
| 228 | db_user | localhost | db_db| Query | 5 | Waiting for table level lock | SELECT count(*) FROM users WHERE createtime>'1396411200' OR createtime='1396411200' |
| 229 | db_user | localhost | db_db| Query | 4 | Waiting for table level …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 FULLTEXT 索引添加到现有表中,但出现以下错误。
1214 - 使用的表类型不支持 FULLTEXT 索引
我正在使用的查询是:
alter table <table name> add FULLTEXT INDEX (column name(s))
Run Code Online (Sandbox Code Playgroud)
相同的查询似乎适用于我的本地主机。我的数据库引擎是 InnoDB,用于本地服务器和实时服务器。
显示创建表显示:
CREATE TABLE `xxx` (
`name1` varchar(50) NOT NULL,
`city1` varchar(30) NOT NULL,
`area1` varchar(100) NOT NULL,
`add1` varchar(100) NOT NULL,
`cont1` varchar(10) NOT NULL,
`gen` varchar(1) NOT NULL,
`type` varchar(10) NOT NULL,
`landm` varchar(30) NOT NULL,
`mo` varchar(10) NOT NULL,
`email` varchar(100) NOT NULL,
`passwd` varchar(100) NOT NULL,
`exp` varchar(10) NOT NULL,
`qual` varchar(30) NOT NULL,
`id` varchar(255) NOT …Run Code Online (Sandbox Code Playgroud) 我有一个MyISAM表(10M行,3.5G,计划达到~80M),我总是无法将其转换为InnoDB.
我试过了 :
ALTER TABLE - 2分钟后失去联系.也许我做错了.
mysqldump- 尝试创建转储然后更改ENGINE=MyISAM为ENGINE=InnoDB.
它开始很好但随着新表中行数的增长(~3M),它变得越来越慢,最后在几个小时后它超时(--reconnect打开).
如果我将缓冲池大小增加到2G,它会在更多行(~6M)之后减慢,但机器会耗尽RAM.
在SHOW PROCESSLIST转储恢复期间,我看到许多查询在"查询结束"状态下停留了2-3分钟.从google-ing无法理解是什么意思.
INSERT INTO ... SELECT * FROM - 创建了相同结构的表并尝试了这一点.在数百万行之后也会减速然后超时.(感谢@ErnestasStankevičius提醒我这个.)服务器:
Aws EC2 4GB Ubuntu14.04
my.cnf:
wait_timeout=28800
connect_timeout=28800
innodb_lock_wait_timeout=28800
net_read_timeout=7200
net_write_timeout=7200
innodb_buffer_pool_size=1G
innodb_io_capacity=100 /*200 is heavy on the machine*/
innodb_flush_log_at_trx_commit=0
reconnect=1
Run Code Online (Sandbox Code Playgroud) 假设有一个表:
name | score
A 100
B 98
C 99
D 99
E 99
F 98
Run Code Online (Sandbox Code Playgroud)
并请求 sql = 'select * from table order by Score desc'
我知道顺序是 100, 99, 99, 99, 98, 98,但是 99 和 98 有几个值。
我正在使用 MyIsam,并且想要确保即使我删除了某些元素,99 和 98 中的顺序也不会更改。例如,如果顺序是 C->D->E 并且我删除了 D,那么我期望是 C->E 但不是 E->C。当订单价值相同时,它有什么逻辑吗?
myisam ×10
mysql ×10
innodb ×5
sql ×3
insert ×1
large-data ×1
locking ×1
performance ×1
select ×1
sql-order-by ×1
unique-index ×1
unique-key ×1
versioning ×1