具有大数据性能的MySQL查询

时间:2017-08-02 01:32:11

标签: php mysql performance pdo

我对MySQL有点新意,我想知道我是否正确使用这些表格和查询:

tb_anuncio

CREATE TABLE `tb_anuncio` (
  `anuncio_id` int(11) NOT NULL auto_increment,
  `anuncio_titulo` varchar(120) NOT NULL,
  `anuncio_valor` decimal(10,2) NOT NULL,
  `anuncio_valorTipo` int(11) default NULL,
  `anuncio_telefone` varchar(20) NOT NULL,
  `anuncio_descricao` text,
  `anuncio_criado` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `bairro_id` int(11) NOT NULL,
  `anuncio_status` int(11) default '0',
  PRIMARY KEY  (`anuncio_id`),
  KEY `ta001_ix` (`bairro_id`)
) ENGINE=InnoDB  DEFAULT charset utf8;

ALTER TABLE `tb_anuncio`
  ADD CONSTRAINT `ta001_ix` FOREIGN KEY (`bairro_id`) REFERENCES `tb_bairro` (`bairro_id`) ON DELETE CASCADE ON UPDATE CASCADE;

tb_estado

CREATE TABLE `tb_estado` (
  `estado_id` int(11) NOT NULL auto_increment,
  `estado_nome` varchar(2) NOT NULL,
  `estado_criado` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `estado_url` varchar(2) NOT NULL,
  PRIMARY KEY  (`estado_id`),
  UNIQUE KEY `estado_url` (`estado_url`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

tb_cidade

CREATE TABLE `tb_cidade` (
  `cidade_id` int(11) NOT NULL auto_increment,
  `cidade_nome` varchar(100) NOT NULL,
  `cidade_criado` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `estado_id` int(11) NOT NULL,
  `cidade_url` varchar(150) NOT NULL,
  PRIMARY KEY  (`cidade_id`),
  UNIQUE KEY `cidade_url` (`cidade_url`),
  KEY `tc001_ix` (`estado_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

ALTER TABLE `tb_cidade`
  ADD CONSTRAINT `tc001_ix` FOREIGN KEY (`estado_id`) REFERENCES `tb_estado` (`estado_id`) ON DELETE CASCADE ON UPDATE CASCADE;

tb_bairro

CREATE TABLE `tb_bairro` (
  `bairro_id` int(11) NOT NULL auto_increment,
  `bairro_nome` varchar(100) NOT NULL,
  `bairro_criado` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `cidade_id` int(11) NOT NULL,
  `bairro_url` varchar(150) NOT NULL,
  PRIMARY KEY  (`bairro_id`),
  UNIQUE KEY `bairro_url` (`bairro_url`),
  KEY `tb001_ix` (`cidade_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

ALTER TABLE `tb_bairro`
  ADD CONSTRAINT `tb001_ix` FOREIGN KEY (`cidade_id`) REFERENCES `tb_cidade` (`cidade_id`) ON DELETE CASCADE ON UPDATE CASCADE;

我正在查询显示某个城市/州的广告,我的查询如下:

查询

select a.anuncio_id,a.anuncio_titulo,a.anuncio_valor,a.anuncio_valorTipo,a.anuncio_descricao
from tb_anuncio a inner join(
tb_bairro b inner join(
tb_cidade c inner join 
tb_estado d on d.estado_id=c.estado_id) on c.cidade_id=b.cidade_id) on b.bairro_id=a.bairro_id 
where a.anuncio_status=1 and d.estado_id=:estado_id and c.cidade_id=:cidade_id and b.bairro_id=:bairro_id 
group by a.anuncio_id 
order by a.anuncio_id desc 
limit :limit

我想知道我是否正确,当这些表格获得大约5k-10k的记录时它会很好用。

我正在使用PHP PDO MySQL。

感谢。

2 个答案:

答案 0 :(得分:1)

虽然它不会影响性能,但编写查询的典型方法在FROM子句中没有括号。另外,我怀疑group by是必要的:

select a.*
from tb_anuncio a inner join
     tb_bairro b
     on b.bairro_id = a.bairro_id inner join
     tb_cidade c 
     on c.cidade_id = b.cidade_id inner join 
     tb_estado e
     on e.estado_id = c.estado_id
where a.anuncio_status = 1 and e.estado_id = :estado_id and 
      c.cidade_id = :cidade_id and b.bairro_id = :bairro_id 
order by a.anuncio_id desc 
limit :limit;

您可以简化此操作,因为您不需要所有join s - join密钥在引用表中:

select a.*
from tb_anuncio a inner join
     tb_bairro b
     on b.bairro_id = a.bairro_id inner join
     tb_cidade c 
     on c.cidade_id = b.cidade_id 
where a.anuncio_status = 1 and c.estado_id = :estado_id and 
      c.cidade_id = :cidade_id and b.bairro_id = :bairro_id 
order by a.anuncio_id desc 
limit :limit;

答案 1 :(得分:0)

我不懂葡萄牙语,但似乎有一个estado包含许多cidades,其中包含许多bairros。如果这是正确的,那么架构是错误的。修复架构将提高性能。

查询中应该有一个 bairro,而GROUP BY中不应包含三个这样的项目。

此外,tb_bairro通常更实用,包括有关cidade和estado的信息, not tb_anuncio。

完成这些操作后,可能会删除INDEX(anuncio_status, bairro_id, anuncio_id) ,从而增加更多性能。

并添加

file_name_01 = os.path.join(input_folder_name,'subject101.dat')
file_DF_01 = pd.read_table(file_name_01, ' ',  header=None)
file_name_02 = os.path.join(input_folder_name,'subject102.dat')
file_DF_02 = pd.read_table(file_name_02, ' ', header=None)
file_name_03 = os.path.join(input_folder_name,'subject103.dat')
file_DF_03 = pd.read_table(file_name_03, ' ', header=None)
file_name_04 = os.path.join(input_folder_name,'subject104.dat')