sql >> Database >  >> RDS >> Mysql

MySQL `FORCE INDEX` use cases?

Ik heb gemerkt dat FORCE INDEX helpt als je meerdere joins en subquery's hebt op VARCHAR-velden waarbij zowel de FK als de waarde waarnaar wordt verwezen niet de primaire sleutel zijn, terwijl je tegelijkertijd een where-clausule in een DATE-veld hebt.

Iets als:

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 zal altijd de PK's en FK's gebruiken, waar u het eerst de betalingsdatum-index in de betalingstabel zou gebruiken, omdat deze de grootste is. Dus een FORCE INDEX(payment_date) op de betalingstafel meedoen zou veel helpen.

Dit is een voorbeeld uit de factureringsdatabase van derden die we op het werk gebruiken. We hadden enorme problemen met de optimalisatie en FORCE INDEX deed het werk meestal. Meestal vonden we de trage katernen met mysqladmin, testten ze met FORCE INDEX en stuurden ze naar de leveranciers om ze te herschrijven in de broncode van de app.

Hier zijn de vier tabellen om meer grip op het voorbeeld te krijgen:

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. MySQL UPDATE-syntaxis met meerdere tabellen met behulp van de WHERE-clausule

  2. Voordelen versus nadelen van het implementeren van een hybride cloudomgeving

  3. Verwijder ouder als er niet naar verwezen wordt door een ander kind

  4. selecteer count(*) uit de tabel van mysql in php