我有一个包含2个长文本列的表,当我获取100行需要5秒时,这很长时间了吗? 也许这是因为我有这两个长文本列?
这是表结构:
CREATE TABLE `tempBusiness2` (
`bussId` int(11) NOT NULL AUTO_INCREMENT,
`nameHe` varchar(200) COLLATE utf8_bin NOT NULL,
`nameAr` varchar(200) COLLATE utf8_bin NOT NULL,
`nameEn` varchar(200) COLLATE utf8_bin NOT NULL,
`addressHe` varchar(200) COLLATE utf8_bin NOT NULL,
`addressAr` varchar(200) COLLATE utf8_bin NOT NULL,
`addressEn` varchar(200) COLLATE utf8_bin NOT NULL,
`x` varchar(200) COLLATE utf8_bin NOT NULL,
`y` varchar(200) COLLATE utf8_bin NOT NULL,
`categoryId` int(11) NOT NULL,
`subcategoryId` int(11) NOT NULL,
`cityId` int(11) NOT NULL,
`cityName` varchar(200) COLLATE utf8_bin NOT NULL,
`phone` varchar(200) COLLATE utf8_bin NOT NULL,
`userDetails` text COLLATE utf8_bin NOT NULL,
`selectedIDFace` tinyint(4) NOT NULL,
`alluserDetails` longtext COLLATE utf8_bin NOT NULL,
`details` varchar(500) COLLATE utf8_bin NOT NULL,
`picture` varchar(200) COLLATE utf8_bin NOT NULL,
`imageUrl` varchar(200) COLLATE utf8_bin NOT NULL,
`fax` varchar(200) COLLATE utf8_bin NOT NULL,
`email` varchar(200) COLLATE utf8_bin NOT NULL,
`facebook` varchar(200) COLLATE utf8_bin NOT NULL,
`trash` tinyint(4) NOT NULL,
`subCategories` varchar(500) COLLATE utf8_bin NOT NULL,
`openHours` varchar(500) COLLATE utf8_bin NOT NULL,
`lastCheckedDuplications` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`bussStatus` tinyint(4) NOT NULL,
`approveStatus` tinyint(4) NOT NULL,
`steps` tinyint(4) NOT NULL DEFAULT '0',
`allDetails` longtext COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`bussId`),
KEY `bussId` (`allDetails`(5),`bussId`),
KEY `face` (`alluserDetails`(5),`userDetails`(5),`bussId`)
) ENGINE=InnoDB AUTO_INCREMENT=2515926 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
我的查询= SELECT * FROM tempBusiness2 LIMIT 100
答案 0 :(得分:1)
如果SELECT * FROM tempBusiness2 LIMIT 100
确实是您的查询,那么没有 INDEX,而否 INDEX会让它运行得更快。
该声明的作用:
但是......由于TEXT和VARCHAR字段的 lot ,它效率不高。在上面提到的B +树中存储的行不超过8K;剩下的就是坐在与之相连的额外街区。 (我不知道有多少额外的块,但我担心它不止一个。)每个额外的块都是另一个磁盘命中。
现在,让我们尝试计算磁盘命中数"。如果您第二次运行此查询(并且具有相当大的innodb_buffer_pool_size),则会有任何磁盘命中。相反,让我们专注于"冷缓存"并计算被触摸的数据块。
如果每个块只有一行(从8KB注释中得出),则需要读取100个块。加上额外的积木 - 一百多个。
普通磁盘每秒可处理100次读取。这总共是几秒钟 - 可能是你经历的5秒!。
现在......可以做些什么?
除非你真的想要所有专栏,否则不要做SELECT *
。通过避免一些庞大的列,您可以避免一些磁盘命中。
innodb_buffer_pool_size应该是可用内存的70%左右。
"垂直分区" 可以帮助。这是您将某些列拆分为“并行”的地方。表。如果列的某些子集实际上是一大块相关的东西,这是很方便的,如果它是"可选的"在某种意义上。加入"将数据重新组合在一起"可能不会比你现在经历的更糟糕。
你真的需要(200)在所有这些领域吗?
你看起来像一个3元素的名字和地址数组。 可能更好,因为另一个表每个bussId最多有3行。
另一方面说明:如果您对所有查询运行EXPLAIN SELECT ...
,您可能会发现"前缀索引"从未使用过:
KEY `bussId` (`allDetails`(5),`bussId`),
KEY `face` (`alluserDetails`(5),`userDetails`(5),`bussId`)
你在他们里面想要什么?相反,请考虑使用FULLTEXT索引。
为什么此表中同时包含city_id
和city_name
?这听起来像是规范化疯狂了。
答案 1 :(得分:0)
是的,这种列需要花费很多时间,只在您需要时返回此列。 而且,你需要在你的桌子上做一个索引。