Existe uma maneira de buscar a quantidade de leituras/gravações feitas em todo o banco de dados (MySql) em um determinado período, por exemplo, a quantidade de leituras/gravações na última hora?
Ran's questions
Eu tenho a seguinte tabela:
CREATE TABLE `timeline_lists` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`list_type` int(11) NOT NULL,
`s_object_id` int(11) NOT NULL DEFAULT '0',
`group_id` int(11) DEFAULT '0',
`new_items_count` int(11) DEFAULT NULL,
`last_accessed_on` datetime DEFAULT NULL,
`last_updated_on` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`,`user_id`),
KEY `unique_index` (`user_id`,`list_type`,`s_object_id`,`group_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
toda vez que executo a seguinte consulta, um novo registro é adicionado:
INSERT INTO `timeline_lists` (`id`,`user_id`,`list_type`,`s_object_id`,`group_id`,`new_items_count`,`last_accessed_on`,`last_updated_on`,`created_at`,`updated_at`)
VALUES
(NULL,18724,11,0,0,5,'2014-09-23 16:37:46',NULL,'2014-09-23 16:37:48','2014-09-23 16:37:48')
ON DUPLICATE KEY UPDATE
`timeline_lists`.`new_items_count`=VALUES(`new_items_count`),
`timeline_lists`.`last_accessed_on`=VALUES(`last_accessed_on`),
`timeline_lists`.`updated_at`=VALUES(`updated_at`)
Eu esperaria que o efeito de índice exclusivo e os campos fossem apenas atualizados, se eu ajustar esta consulta 5 vezes, obteria 5 registros no banco de dados em vez de apenas 1.
O que estou perdendo aqui?
Por favor, olhe a seguinte tabela Mysql: http://pastebin.com/b0NDSbdz
Eu particionei a tabela sent_at
e estou certificando-me de que a maioria das consultas passe sent_at
. preciso incluir sent_at
em todos os índices?
você identifica algum índice redundante em potencial?
quando incluo o sent_at
nos índices, tem que ser o primeiro campo na declaração do índice?
Eu tenho uma tabela MySql chamada twitter_statuses
que, como o título sugere, contém os status do Twitter. aqui está a estrutura da tabela.
esta tabela contém todos os tipos de caracteres na coluna de texto, e algumas das colunas contêm objetos Ruby que são multilinhados.
Estou tentando selecionar alguns dos registros em um arquivo e, em seguida, carregá-los em uma nova tabela, mas por causa de todos os caracteres especiais, algumas das linhas ficam "confusas".
aqui está a consulta que eu uso para despejar os status
aqui está a consulta que uso para recarregar os status despejados
Como você pode ver, tentei substituir as vírgulas na coluna de texto ****
para evitar que dividissem os campos e substituí a nova linha nas colunas de várias linhas ( urls
, hashtags
, user_mentions
) para evitar "cortar a linha" ao despejar o arquivo em CSV.
atualmente, os campos de várias linhas carregam muito bem (a substituição do novo caractere de linha funciona) meu problema id com outros caracteres que aparecem em outros campos (todo tipo de caractere) com causa para dividir colunas.
alguma idéia sobre o que eu poderia mudar lá?
Eu tenho a seguinte tabela :
CREATE TABLE `twitter_relationships` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`source_twitter_id` bigint(20) NOT NULL,
`target_twitter_id` bigint(20) NOT NULL,
`relationship_status` tinyint(1) NOT NULL,
`status_change_date` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`,`user_id`),
UNIQUE KEY `source_and_target` (`user_id`,`source_twitter_id`,`target_twitter_id`),
KEY `target_status_and_change_date_index` (`user_id`,`target_twitter_id`,`relationship_status`,`status_change_date`),
KEY `user_id_index` (`user_id`,`status_change_date`)
) ENGINE=InnoDB AUTO_INCREMENT=116597775 DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (user_id)
PARTITIONS 1000 */
Esta tabela é bem grande, aproximadamente 150 milhões de registros.
E tenho a seguinte consulta:
SELECT target_twitter_id
FROM `twitter_relationships`
WHERE (`twitter_relationships`.`relationship_status` = ?
AND `twitter_relationships`.`user_id` = ?
AND `twitter_relationships`.`source_twitter_id` = ?)
LIMIT ?, ?
Aqui está a explicação para esta consulta :
id: 1
select_type: SIMPLE
table: twitter_relationships
type: ref
possible_keys: source_and_target,target_status_and_change_date_index,user_id_index
key: source_and_target
key_len: 12
ref: const,const
rows: 8560582
Extra: Using where
Alguma ideia do que posso fazer na consulta ou mesmo na estrutura da tabela para agilizar essa consulta?
Digamos que eu tenha a seguinte tabela:
CREATE TABLE `my_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`relationship_status` varchar(48) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
e digamos que esta tabela tenha muitos registros: 100M
Eu tenho 2 valores possíveis para relationship_status
: 'following' ou 'not_following'
já que eu quero reduzir o tamanho do banco de dados (tamanho no disco rígido), como isso afetaria se eu mudasse relationship_status
para Boolean em vez de varchar(48) (onde if pode definir 0 como não seguinte e 1 como seguinte)?
qual tipo de coluna você usaria? minúsculoint?
Atualmente tenho um Master com 2 slaves, todos rodando MySql 5.5.
Quais são as limitações na quantidade de escravos que posso conectar a um único mestre? quais parâmetros devem ser levados em consideração?
Eu tenho uma configuração de replicação mestre/escravo, ambos os servidores executam o MySQL 5.1.61.
Desejo atualizar o servidor mestre para uma máquina mais forte com o seguinte:
- 2 processadores - 6 núcleos cada
- 48 GB de RAM
Para utilizar os dois processadores, preciso instalar o plug-in InnoDB
Eu tenho algumas perguntas:
- É possível instalar o plugin InnoDB apenas no master e não no slave?
- Existem outras implicações para a instalação do plug-in?
- Quais parâmetros preciso alterar em my.cnf para melhor utilizar o plug-in e as opções de vários núcleos?
- Algum tutorial recomendado para instalar o plugin?
Tenho uma replicação Master/Slave (usando MySql 5.1/InnoDB).
Atualmente, meu mestre e escravo estão sendo executados no mesmo tipo de servidor (32 GB de RAM, 2 x Intel Xeon 5520 Quad Core 2,26 GHz (8 núcleos)) e têm o mesmo tipo de configuração (em termos de innodb_pool_size etc.)
Estou pensando em atualizar meu mestre para uma máquina mais forte (48 GB de RAM, 2 x Intel Xeon 5640 Six Core 2,26 GHz (12 núcleos)).
Minha pergunta é: É possível atualizar apenas o mestre (aumentar seu buffer_bool_size etc.) e deixar o escravo em sua configuração atual?
Eu tenho um banco de dados cujo tamanho total é ~ 44 GB, dos quais ibdata1 é ~ 35 GB. Isso não faz sentido, já que o tamanho dos dados não deve ser superior a 10 GB.
Eu uso a seguinte consulta para obter uma estimativa do tamanho dos dados:
SELECT CONCAT(table_schema, '.', table_name),
CONCAT(ROUND(table_rows / 1000000, 2), 'M') rows,
CONCAT(ROUND(data_length / ( 1024 * 1024 * 1024 ), 2), 'G') DATA,
CONCAT(ROUND(index_length / ( 1024 * 1024 * 1024 ), 2), 'G') idx,
CONCAT(ROUND(( data_length + index_length ) / ( 1024 * 1024 * 1024 ), 2), 'G') total_size,
ROUND(index_length / data_length, 2) idxfrac
FROM information_schema.TABLES
ORDER BY data_length + index_length DESC
LIMIT 30;
Alguma ideia de como limpar o ibdata1 e por que ele cresceu tanto?
BTW, eu uso innodb_file_per_table
Os servidores da nossa empresa estão atualmente hospedados em um VPS e decidimos migrar para servidores dedicados.
Ao escolher o melhor hardware para um servidor de banco de dados, em que devemos investir mais recursos: melhor CPU (mais núcleos)? ou mais memória RAM?
Onde está o melhor ROI?
Alguma sugestão?
Quero tornar meu escravo MySql somente leitura, procurei e encontrei a opção read_only , mas diz que usuários com super privalges ainda podem escrever (se entendi o texto corretamente), aqui estão as concessões para meu aplicativo:
GRANT RELOAD, PROCESS ON *.* TO 'my_app'@'%' IDENTIFIED BY PASSWORD '*'
GRANT ALL PRIVILEGES ON `my_app`.* TO 'my_app'@'%'
o aplicativo será capaz de escrever para o escravo?
estou tentando criar a seguinte tabela:
CREATE TABLE `s_relations_with_partition` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`source_persona_id` int(11) NOT NULL,
`relation_type` int(11) NOT NULL,
`message_id` int(11) DEFAULT NULL,
`reply_to_message_id` int(11) DEFAULT NULL,
`reshare_of_message_id` int(11) DEFAULT NULL,
`target_object_id` int(11) DEFAULT NULL,
`target_persona_id` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`sent_at` int(11) DEFAULT NULL,
PRIMARY KEY (`id`,`sent_at`),
UNIQUE KEY `unique_target_persona` (`source_persona_id`,`relation_type`,`message_id`,`target_persona_id`),
UNIQUE KEY `unique_target_object` (`source_persona_id`,`relation_type`,`message_id`,`target_object_id`),
KEY `message_id_index` (`message_id`),
KEY `reshare_of_message_id_index` (`reshare_of_message_id`),
KEY `reply_to_message_id_index` (`reply_to_message_id`),
KEY `source_and_target_object_index` (`source_persona_id`,`target_object_id`),
KEY `source_target_persona_index` (`source_persona_id`,`target_persona_id`),
KEY `target_persona_relation_type_message_id_index` (`target_persona_id`,`relation_type`,`message_id`),
KEY `sent_at_index` (`sent_at`),
KEY `source_persona_sent_at_index` (`source_persona_id`,`sent_at`),
KEY `target_persona_sent_at_index` (`target_persona_id`,`sent_at`),
KEY `target_object_sent_at_index` (`target_object_id`,`sent_at`)
) ENGINE=InnoDB
PARTITION BY RANGE (sent_at) (
PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-02-01 00:00:00') ),
PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-03-01 00:00:00') ),
PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-04-01 00:00:00') ),
PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-05-01 00:00:00') ),
PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-06-01 00:00:00') ),
PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-07-01 00:00:00') ),
PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-08-01 00:00:00') ),
PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-09-01 00:00:00') ),
PARTITION p9 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-10-01 00:00:00') ),
PARTITION p10 VALUES LESS THAN (MAXVALUE)
);
e recebo o seguinte erro:
A UNIQUE INDEX must include all columns in the table's partitioning function
não é possível adicionar sent_at
(carimbo de data/hora unix) ao índice exclusivo.
alguma ideia de como posso implementar uma partição de intervalo de datas nessa tabela?
Sou novo no particionamento MySql e tenho uma dúvida sobre índices. digamos que eu tenha a seguinte tabela:
CREATE TABLE `members` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`member_rating` int(11) DEFAULT '0',
`persona_id` int(11) NOT NULL,
`high_value_type` int(11) DEFAULT NULL,
PRIMARY KEY (`id`,`user_id`),
UNIQUE KEY `user_id` (`user_id`,`persona_id`),
KEY `member_rating_index` (`member_rating`),
KEY `persona_index` (`persona_id`),
KEY `high_value_members_index` (`user_id`,`high_value_type`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (user_id)
PARTITIONS 1000 */
pelo que entendi, tudo funcionará bem desde que eu consulte a tabela enquanto forneço user_id
, minha pergunta é: como a tabela funcionará quando eu fizer uma consulta sem user_id
, diga algo como:
SELECT * FROM members where persona_id=3
alguma ideia?
ps estou rodando no MySql 5.1 / innodb
Eu tenho um grande banco de dados MySql (150 GB) e só agora notei que o innodb_file_per_table
está definido para off
o que faz com que todo o banco de dados seja hospedado em um único arquivo ( ibdata1
). Eu quero ativar innodb_file_per_table
e dividir retroativamente o banco de dados em vários arquivos, qual é a melhor maneira de fazer isso?
Tenho as seguintes tabelas:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`account_data` text COLLATE utf8_unicode_ci,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`twitter_username` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`crypted_password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password_salt` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`persistence_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`single_access_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`perishable_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`login_count` int(11) NOT NULL DEFAULT '0',
`failed_login_count` int(11) NOT NULL DEFAULT '0',
`last_request_at` datetime DEFAULT NULL,
`current_login_at` datetime DEFAULT NULL,
`last_login_at` datetime DEFAULT NULL,
`current_login_ip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_login_ip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`is_admin` tinyint(1) DEFAULT '0',
`referrer_id` int(11) DEFAULT NULL,
`partner` tinyint(1) DEFAULT '0',
`subscription_type` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'free',
`workflow_state` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`persona_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `persona_index` (`persona_id`)
) ENGINE=InnoDB
e a mesa:
CREATE TABLE `user_actions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`action_type` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`module` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`data` text COLLATE utf8_unicode_ci,
`timestamp` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id_index` (`user_id`),
KEY `action_type_index` (`action_type`),
KEY `user_action_type_index` (`user_id`,`action_type`),
KEY `timestamp_index` (`timestamp`),
KEY `user_id_timestamp_index` (`user_id`,`timestamp`)
) ENGINE=InnoDB
o problema está na seguinte consulta:
SELECT user_actions.*, users.twitter_username, users.email FROM `user_actions`
INNER JOIN users ON (user_actions.user_id=users.id) ORDER BY timestamp DESC LIMIT 0, 30
aqui está a explicação:
user_actions
The table was retrieved with this index: user_id_timestamp_index
You can speed up this query by querying only fields that are within the index. Or you can create an index that includes every field in your query, including the primary key.
Approximately 76 rows of this table were scanned.
users
This table was retrieved with a full table scan, which is often quite bad for performance, unless you only retrieve a few rows.
The table was retrieved with this index:
No index was used in this part of the query.
A temporary table was created to access this part of the query, which can cause poor performance. This typically happens if the query contains GROUP BY and ORDER BY clauses that list columns differently.
MySQL had to do an extra pass to retrieve the rows in sorted order, which is a cause of poor performance but sometimes unavoidable.
You can speed up this query by querying only fields that are within the index. Or you can create an index that includes every field in your query, including the primary key.
Approximately 3445 rows of this table were scanned.
esta consulta demora muito para ser executada, alguma ideia de como melhorar?
Eu tenho uma tabela InnoDB que quero alterar. A tabela tem cerca de 80 milhões de linhas e encerra alguns índices.
Quero mudar o nome de uma das colunas e adicionar mais alguns índices.
- Qual é a maneira mais rápida de fazer isso (supondo que eu possa sofrer até mesmo tempo de inatividade - o servidor é um escravo não utilizado)?
- É um "simples"
alter table
, a solução mais rápida?
Neste momento, tudo o que me importa é a velocidade :)
Eu tenho um banco de dados MySql de 30 GB, feito de tabelas innoDB. atualmente o conjunto de caracteres das tabelas é: "utf8_unicode_ci" e quero mudar para "utf8_general_ci", qual a melhor maneira de fazer isso? atualmente estou passando por cada mesa e correndo ALTER TABLE some_table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
e demora uma eternidade ... existe uma maneira melhor?