调整my.cnf / php.ini的建议和对索引较差的数据集进行分区,缺少PK

时间:2012-04-16 06:14:53

标签: mysql query-optimization indexing my.cnf

我们现在已经尝试了一段时间,我们遇到了一个特别具有挑战性和非常大的数据集,我发现创建有效索引和主键的方法很少(除非对数据库进行全面彻底的重新设计)这是一个经济的选择)。我正在寻找关于如何改变查询或表格结构(分区等)的建议 - 长话短说我们最终耗费了大量时间来进行笛卡尔连接。

这是细节:

我这里有3个关键示例表,但有时加入2-3与结果相似的内容:

如果我指出(??)我正在摸不着头脑(这真的是最好的设置方法吗?请加入)

样本 - 我们的主要关注表,因为它处理我们的所有示例案例人口统计信息 字段:

  • sampleid(非PK但是UNIQUE ??)varchar(255) - 大多数数据是10位整数(??),这是一个特定报告的数据库中的唯一ID。
  • case - varchar(255) - 大多数是10-12位整数(??),这是唯一id的第二种形式,但是1000001的case值可能在其他表中有1-20 sampleid与它相关联(稍后)提供顺序/时间顺序信息。 (像日记)

adj_samples

包含样本之外的扩展/注释数据,通过SampleID链接到样本

字段:

  • RecordID(PK)只是一个autonum,记录记录(??)。

  • 在一个样本id->中链接到样本表的SampleID对于许多adj_case记录 - 作为样本可能有几个注释注释,或与之相关的其他minuatie,这是 adj_case 表的目的。

  • ProbableID - int,只是我们的内部代码信息代码。

结果 字段:

  • SampleID varchar 255(也可能是int)
  • 结果(从我所看到的仅限于100个len char字段,但字段len设置为255 varchar)

基本上通过SampleID将adj_samples链接到一个DISTINCT(SampleID)到多个结果,结果字段指示不同级别的信息比其他更详细,varchar 50-100 char in len(NOT 255 varchar?)

表格大小

samples 2,946,614 rows, MyISAM - 384MB
adj_samples 12,098,910 rows, myISAM, 1.3 GB
result 13,011,880 rows 428,508 KB

示例查询将为我们提供给定内部ID(probableID)的所有案例计数

SELECT r.result as result
, COUNT(DISTINCT p.`case`) as ResultCount
FROM Adj_Samples as
LEFT JOIN samples s
ON as.SampleID = s.SampleID
LEFT JOIN results r
ON as.SampleID = r.SampleID
WHERE ProbableID = '101'
AND ProbableID NOT IN #(subquery to table of banned codes we dont want to see)
GROUP BY r.result
ORDER BY COUNT(DISTINCT p.`case`)                  

我们有时必须加入几个类似于结果的表格,因为还有其他表格包含相关信息 - 并不罕见找到5-6堆叠而且它完全是笛卡尔式的。我们已经将最好的索引编入索引,但是我们正在处理那么多可能是键的varchars(results.result是一个索引,但是长度为100-255个字符!)。

我想知道样本中奇怪的未使用的字段是PK,在我看来,SampleID应该是PK,因为它们应该是唯一的但是错误引入了重复项?

我正在寻找类似于分区策略的东西,并且只是一般地在盒子外思考以实现这一目标。此信息对数字代码和一对一表用作中间索引表的方式没有太大影响。

所以这是我的my.cnf,如果它有任何帮助,因为我们有重大的性能问题,该盒子是一个8核心英特尔专用centos5.5与16GB的RAM。我发现通常需要在这些大型连接上写入磁盘。我认为我应该处理的第一件事是我们存储的数据的正确字段大小,10位整数的var 255似乎是浪费

超出实际需要的字段长度是否会影响表格大小的性能?

还附加了db schema的图片 Demo table schema

解释:我真的咬了解解释中的最初Adj_Samples - 它转到使用where;使用临时;使用Filesort然后另一个使用where 4行的结果。都属于ref。

以下是my.cnf:

[mysqld]
socket          = /var/lib/mysql/mysql.sock
key_buffer = 2048MB
max_allowed_packet = 16MB
group_concat_max_len = 16MB
table_cache = 1024MB
sort_buffer_size = 4MB
read_buffer_size = 4MB
read_rnd_buffer_size = 16MB
myisam_sort_buffer_size = 128MB
thread_cache_size = 16
thread_concurrency = 16
query_cache_type = 1
query_cache_size = 512MB
tmpdir = /home/tmp
join_buffer_size = 4MB
max_heap_table_size = 3GB
tmp_table_size = 512MB
log-slow-queries
long_query_time = 20
no-auto-rehash
[isamchk]
key_buffer =1024M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M

[myisamchk]
key_buffer = 4096M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M

**This part strikes me as odd as I don't believe we are using any innodb tables**
innodb_data_home_dir = /var/lib/mysql/
innodb_data_file_path = ibdata1:2000M;ibdata2:10M:autoextend
innodb_log_group_home_dir = /var/lib/mysql/
innodb_log_arch_dir = /var/lib/mysql/
innodb_buffer_pool_size = 1024M
innodb_additional_mem_pool_size = 20M
**comment form whoever:** Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 100M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

感谢您的所有帮助,我已经有6个月的时间学习mysql并且学到了很多东西,但我很期待在这个练习中向大家学习更多。

在bash:top我看到我的mysql进程只能达到30%的内存,但在200-400%的CPU上运行是正常的,还是我的my.cnf搞砸了这一切?

0 个答案:

没有答案