sql >> Databáze >  >> RDS >> Mysql

Případy použití MySQL `FORCE INDEX`?

Všiml jsem si, že FORCE INDEX pomáhá, když máte více spojení a dílčích dotazů na pole VARCHAR, kde FK i odkazovaná hodnota nejsou primárním klíčem, a zároveň mají klauzuli where v poli DATE.

Něco jako:

SELECT NAME, a.reference_no, i.value, p.value FROM customers AS c
INNER JOIN accounts AS a ON c.id = a.customer_id
INNER JOIN invoices AS i ON i.reference_no = a.reference_no
INNER JOIN payments AS p ON p.invoice_no = i.invoice_no
WHERE payments.date >= '2011-09-01' AND DATE < '2011-10-01';

mysql bude vždy používat PK a FK, kde byste měli nejprve použít index payment_date v tabulce plateb, protože je největší. Tedy FORCE INDEX(payment_date) spojení v tabulce plateb by hodně pomohlo.

Toto je příklad z fakturační databáze třetích stran, kterou používáme v práci. Měli jsme obrovské problémy s optimalizací a FORCE INDEX většinu času zvládl. Obvykle jsme našli pomalé požadavky pomocí mysqladmin, otestovali je pomocí FORCE INDEX a poslali je prodejcům, aby je přepsali do zdrojového kódu aplikace.

Zde jsou čtyři tabulky pro lepší pochopení příkladu:

CREATE TABLE `customers` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(100) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

CREATE TABLE `accounts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `customer_id` int(11) NOT NULL,
  `reference_no` varchar(10) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `reference_no_uniq` (`reference_no`),
  KEY `FK_accounts` (`customer_id`),
  CONSTRAINT `FK_accounts` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;

CREATE TABLE `invoices` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `reference_no` varchar(10) NOT NULL,
  `invoice_no` varchar(10) NOT NULL,
  `value` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `invoice_no_uniq` (`invoice_no`),
  KEY `FK_invoices` (`reference_no`),
  CONSTRAINT `FK_invoices` FOREIGN KEY (`reference_no`) REFERENCES `accounts` (`reference_no`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;

CREATE TABLE `payments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `invoice_no` varchar(10) NOT NULL,
  `value` int(11) NOT NULL,
  `date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_payments` (`invoice_no`),
  KEY `payment_date` (`date`),
  CONSTRAINT `FK_payments` FOREIGN KEY (`invoice_no`) REFERENCES `invoices` (`invoice_no`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;


  1. Používá se Mysql utf32_unicode_ci a html znaková sada utf-8, ale objeví se znak �

  2. Prázdný příkaz v T-SQL

  3. Jak vybrat top 1 a seřadit podle data v Oracle SQL?

  4. MySQL s omezením Soft-Deletion, Unique Key a Foreign Key