0

我不是 MySQL 专家,我遇到了问题。我有一张表,目前有 16GB 的数据,而且还会进一步增长。表的结构如下所示,

CREATE TABLE `t_xyz_tracking` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`word` VARCHAR(200) NOT NULL,
`xyzId` BIGINT(100) NOT NULL,
`xyzText` VARCHAR(800) NULL DEFAULT NULL,
`language` VARCHAR(2000) NULL DEFAULT NULL,
`links` VARCHAR(2000) NULL DEFAULT NULL,
`xyzType` VARCHAR(20) NULL DEFAULT NULL,
`source` VARCHAR(1500) NULL DEFAULT NULL,
`sourceStripped` TEXT NULL,
`isTruncated` VARCHAR(40) NULL DEFAULT NULL,
`inReplyToStatusId` BIGINT(30) NULL DEFAULT NULL,
`inReplyToUserId` INT(11) NULL DEFAULT NULL,
`rtUsrProfilePicUrl` TEXT NULL,
`isFavorited` VARCHAR(40) NULL DEFAULT NULL,
`inReplyToScreenName` VARCHAR(40) NULL DEFAULT NULL,
`latitude` BIGINT(100) NOT NULL,
`longitude` BIGINT(100) NOT NULL,
`rexyzStatus` VARCHAR(40) NULL DEFAULT NULL,
`statusInReplyToStatusId` BIGINT(100) NOT NULL,
`statusInReplyToUserId` BIGINT(100) NOT NULL,
`statusFavorited` VARCHAR(40) NULL DEFAULT NULL,
`statusInReplyToScreenName` TEXT NULL,
`screenName` TEXT NULL,
`profilePicUrl` TEXT NULL,
`xyzId` BIGINT(100) NOT NULL,
`name` TEXT NULL,
`location` VARCHAR(200) NULL DEFAULT NULL,
`bio` TEXT NULL,
`url` TEXT NULL COLLATE 'latin1_swedish_ci',
`utcOffset` INT(11) NULL DEFAULT NULL,
`timeZone` VARCHAR(100) NULL DEFAULT NULL,
`frenCnt` BIGINT(20) NULL DEFAULT '0',
`createdAt` DATETIME NULL DEFAULT NULL,
`createdOnGMT` VARCHAR(40) NULL DEFAULT NULL,
`createdOnServerTime` DATETIME NULL DEFAULT NULL,
`follCnt` BIGINT(20) NULL DEFAULT '0',
`favCnt` BIGINT(20) NULL DEFAULT '0',
`totStatusCnt` BIGINT(20) NULL DEFAULT NULL,
`usrCrtDate` VARCHAR(200) NULL DEFAULT NULL,
`humanSentiment` VARCHAR(30) NULL DEFAULT NULL,
`replied` BIT(1) NULL DEFAULT NULL,
`replyMsg` TEXT NULL,
`classified` INT(32) NULL DEFAULT NULL,
`createdOnGMTDate` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `id` (`id`, `word`),
INDEX `word_index` (`word`) USING BTREE,
INDEX `classified_index` (`classified`) USING BTREE,
INDEX `createdOnGMT_index` (`createdOnGMT`) USING BTREE,
INDEX `location_index` (`location`) USING BTREE,
INDEX `word_createdOnGMT` (`word`, `createdOnGMT`),
INDEX `timeZone` (`timeZone`) USING BTREE,
INDEX `language` (`language`(255)) USING BTREE,
INDEX `source` (`source`(255)) USING BTREE,
INDEX `xyzId` (`xyzId`) USING BTREE,
INDEX `getunclassified_index` (`classified`, `xyzType`) USING BTREE,
INDEX `createdOnGMTDate_index` (`createdOnGMTDate`, `word`) USING BTREE,
INDEX `links` (`links`(255)) USING BTREE,
INDEX `xyzType_classified` (`classified`, `xyzType`) USING BTREE,
INDEX `word_createdOnGMTDate` (`word`, `createdOnGMTDate`) USING BTREE
    )COLLATE='utf8_general_ci'
    ENGINE=InnoDB
    ROW_FORMAT=DEFAULT
    AUTO_INCREMENT=17540328

该表上的查询现在运行缓慢,我预计它们会进一步减慢,我的服务器配置如下所示,

Intel Xeon E5220 @2.27GHz(2 个处理器)12GB Ram Windows 2008 Server R2

my.ini 文件详细信息如下,

default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=300
query_cache_size=0
table_cache=256
tmp_table_size=205M
thread_cache_size=8
myisam_max_sort_file_size=3G
myisam_sort_buffer_size=410M
key_buffer_size=354M
read_buffer_size=64K
read_rnd_buffer_size=256K
sort_buffer_size = 64M
join_buffer_size = 64M
thread_cache_size = 8
thread_concurrency = 8
query_cache_size = 128M
innodb_additional_mem_pool_size=15M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=30M
innodb_buffer_pool_size=6G
innodb_log_file_size=343M
innodb_thread_concurrency=44
max_allowed_packet = 16M
slow_query_log
long_query_time = 6

可以做些什么来提高性能,

  1. 转换为 MyISAM 表会有所帮助,我有 INNODB,因为该表具有频繁的写入甚至更频繁的读取。
  2. 我注意到磁盘 I/O 很高,有时高达 20-40MB/秒

谢谢,罗希特

4

4 回答 4

5

一个建议是运行

SELECT * FROM t_xyz_tracking PROCEDURE ANALYSE()

PROCEDURE ANALYZE将根据表中的数据告诉您表中列的建议类型。这应该有助于提高您的效率。

于 2011-01-06T17:19:15.207 回答
1

所有 NULLable 列都可能被移动到单独的表中。检查每列中值的百分比为 NULL,如果它相对较高 - 将其移动到单独的表中。

接下来,您可能想考虑哪些列被经常访问,哪些列被访问相对较少。很少使用的列也可以移动到单独的表中。

于 2011-01-06T17:28:40.687 回答
1

当您的 mysql 服务器太慢时,一个好主意是激活“慢查询日志”,然后研究其中显示的查询。

这极大地帮助了我避免由于一些业余的书面查询而导致的一些可能的灾难性故障。

于 2011-02-09T11:11:25.353 回答
0

就在我的脑海中,看起来你正在使用TEXT你不应该使用的类型。TEXT 是一个 CLOB(认为 BLOB 仅用于字符)。如果你有一个 url,VARCHAR(255) 可能会更好。一个名字,50个字符还不够吗?

运行缓慢的查询是否在使用索引?

您的“isXXX”字段可以更改为 BOOLEAN(或 tinyint(1))吗?

于 2011-01-06T17:09:41.190 回答