sql >> Database teknologi >  >> RDS >> Mysql

MySQL `FORCE INDEX` brugssager?

Jeg har bemærket, at FORCE INDEX hjælper, når du har flere joinforbindelser og underforespørgsler på VARCHAR-felter, hvor både FK-værdien og den refererede værdi ikke er den primære nøgle, mens du samtidig har where-sætning i et DATE-felt.

Noget som:

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 vil altid bruge PK'erne og FK'erne, hvor du vil bruge betalingsdato-indekset på betalingstabellen først, da det er det største. Altså en FORCE INDEX(payment_date) på betalingstabellen ville join hjælpe meget.

Dette er et eksempel fra tredjeparts faktureringsdatabase, som vi bruger på arbejdet. Vi havde store problemer med optimering, og FORCE INDEX klarede arbejdet det meste af tiden. Normalt fandt vi de langsomme quires med mysqladmin, testede dem med FORCE INDEX og sendte dem til leverandørerne for at omskrive dem i kildekoden til appen.

Her er de fire tabeller for at få et bedre greb om eksemplet:

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. Bedste databasesoftware til udviklere (2022-udgaven)

  2. Sådan fungerer SUBSTRING_INDEX() i MariaDB

  3. Hvordan installeres Oracle Instant Client på en Mac?

  4. SQL-forespørgsel til at opdele kolonnedata i rækker