标签: myisam

如何更安全地使用 MyISAM 表?

我喜欢 InnoDB 的安全性、一致性和自检性。

但我需要 MyISAM 的速度和轻量级。

我怎样才能使 MyISAM 不太容易因崩溃、错误数据等而损坏?通过检查(检查表或myisamchk)需要很长时间。

我不是在要求事务安全——这就是 InnoDB 的用途。但我确实想要一个可以快速重启而不是几小时(或几天!)之后的数据库。

更新:我不是在问如何更快地将数据加载到表中。我已经对此表示反对,并确定将 MyISAM 表用于我的 LOAD DATA 会快得多。我现在所追求的是降低使用 MyISAM 表的风险。也就是说,减少损坏的机会,提高恢复速度。

mysql myisam innodb database-integrity

5
推荐指数
1
解决办法
3395
查看次数

MySQL+MyISAM中的“系统锁”

我注意到我们的 MySQL 服务器上的“显示进程列表”表示许多线程处于“系统锁定”状态,通常后面只是“锁定”,后者是我所期望的,因为我们有一些选择锁定在更新/插入后面一个 MyISAM 表。

但是“系统锁定”显示的不仅仅是“锁定”(根据探查器,有时简单的选择会增加长达 2 秒的时间),而且我不明白它表示什么。我在网上找不到太多关于系统锁的信息,但那里主要讨论多个 mysqld 访问同一个数据库的情况,这不是我的情况。此外,我的“跳过外部锁定”变量是错误的。

有人有这方面的经验吗?

附录:

如果有帮助的话,我倾向于在进程列表中看到更多的系统锁比表锁(“锁定”)多,大约为 3 比 1。是否有可能由于某种原因输出“系统锁”以实现有效的常规表锁定?

mysql sql myisam locking

5
推荐指数
1
解决办法
6298
查看次数

MyISAM仅在过程内选择锁定插入

我们有哪些行获得插入只有表底部的大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 select myisam stored-procedures insert

5
推荐指数
1
解决办法
1156
查看次数

MyISAM唯一键被切断为64字节,导致冲突

我有一个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)

mysql myisam unique-index unique-key mysql-error-1062

5
推荐指数
2
解决办法
2330
查看次数

MySQL InnoDB查询性能

我正在尝试优化一个简单的SQL查询,该查询将在很多次数据上运行.

这是场景:

  • MySQL与InnoDB表
  • 在where和join中使用的所有字段都是Indexed.表有FK.
  • 我不需要整个查询缓存,但每个表的缓存都是可能的.
  • 表有更多更新/插入的读取.

一个真实的查询:

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)

一些测试结果:

  • 平均查询时间:2,3374s
  • 测试表包含真实表的第十部分数据(甚至更少),例如big_test_table的75.000行.
  • 查询返回(在测试用例中)6500行.
  • Navicat表示99.95%的查询时间用于"发送数据"
  • 我尝试过MyISAM,平均查询时间是:2,1898s

如何改进查询或数据库方案?

最好连接我的年/周字段和[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 performance myisam innodb

5
推荐指数
1
解决办法
4724
查看次数

如何使用全文索引进行精确匹配?

我有一个带有全文索引的 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 myisam full-text-search

5
推荐指数
1
解决办法
7131
查看次数

等待 MySQL 表上的表级锁

最近几天,我的网站有时变得非常慢。我开始尽我所能进行调查。我看到 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)

mysql sql myisam innodb

5
推荐指数
1
解决办法
5万
查看次数

使用 InnoDB 进行全文搜索

我正在尝试将 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)

mysql versioning myisam innodb full-text-search

5
推荐指数
1
解决办法
1549
查看次数

将大型MyISAM表转换为InnoDB

我有一个MyISAM表(10M行,3.5G,计划达到~80M),我总是无法将其转换为InnoDB.

我试过了 :

  • ALTER TABLE - 2分钟后失去联系.也许我做错了.

  • mysqldump- 尝试创建转储然后更改ENGINE=MyISAMENGINE=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)

mysql myisam innodb large-data

5
推荐指数
1
解决办法
593
查看次数

如果它们的值相同,“ORDER BY”如何排序?

假设有一个表:

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。当订单价值相同时,它有什么逻辑吗?

mysql sql myisam sql-order-by

5
推荐指数
1
解决办法
1万
查看次数