Intereting Posts
сообщение «недостаточное количество данных для изображения» при открытии PDF-файла __destruct в __construct? Позвольте пользователям создавать свои собственные настраиваемые параметры меню, сохраняя при этом значения по умолчанию для приложений включить php-файл только при определенных разрешениях экрана как ограничить цикл foreach тремя контурами PHP sendmail работает в командной строке Ubuntu, но не из файла php Объединить значения флажка с помощью php mysql PHP: как читать текущую дату / время с сервера, а не из php.ini Где лучше всего хранить соль для пароля для веб-сайта? Синтаксис PHP для массивов: различное поведение между версиями PHP Как заставить построитель запросов выводить свой необработанный SQL-запрос в виде строки? Magic_quotes_gpc = 1, на которые влияют суперглобалы? Удалить числовой префикс из строки – PHP regex Являются mysqli_result :: free и mysqli_stmt :: free_result одинаковыми? как защитить изображения внутри папки загрузки от просмотра кем-либо ЗА ИСКЛЮЧЕНИЕМ admin

php & mySQL: запрос не использует индекс в соединении таблицы

Я пытаюсь перечислить всю информацию book_sales для конкретного автора книги. Поэтому у меня есть запрос, и он не использует Index для поиска записей.

Ниже представлена ​​моя структура таблиц:

-- Table structure for table `books` CREATE TABLE IF NOT EXISTS `books` ( `book_id` int(11) NOT NULL auto_increment, `author_id` int(11) unsigned NOT NULL, `book_type_id` int(11) NOT NULL, `book_title` varchar(50) NOT NULL, `book_price` smallint(4) NOT NULL, `in_stock` char(1) NOT NULL, PRIMARY KEY (`book_id`), KEY `book_type_id` (`book_type_id`), KEY `author_id` (`author_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; -- Dumping data for table `books` INSERT INTO `books` (`book_id`, `author_id`, `book_type_id`, `book_title`, `book_price`, `in_stock`) VALUES (1, 1, 1, 'My Book 1', 10, 'y'), (2, 2, 1, 'My Book 2', 20, 'n'), (3, 1, 2, 'My Book 3', 30, 'y'), (4, 3, 3, 'My Book 4', 40, 'y'), (5, 4, 2, 'My Book 5', 50, 'n'), (6, 1, 1, 'My Book 6', 60, 'y'), (7, 5, 3, 'My Book 7', 70, 'n'), (8, 6, 2, 'My Book 8', 80, 'n'), (9, 7, 1, 'My Book 9', 90, 'y'), (10, 8, 3, 'My Book 10', 100, 'n'); -- Table structure for table `book_sales` CREATE TABLE IF NOT EXISTS `book_sales` ( `sale_id` int(11) NOT NULL auto_increment, `book_id` int(11) NOT NULL, `sale_amount` decimal(8,2) NOT NULL default '0.00', `time` datetime NOT NULL default '0000-00-00 00:00:00', `price` smallint(8) NOT NULL, PRIMARY KEY (`sale_id`), KEY `book_id` (`book_id`), KEY `price` (`price`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; -- Dumping data for table `book_sales` INSERT INTO `book_sales` (`sale_id`, `book_id`, `sale_amount`, `time`, `price`) VALUES (1, 1, '10.00', '2010-02-23 10:00:00', 20), (2, 1, '20.00', '2010-02-24 11:00:00', 20); 

Мой запрос:

 SELECT sale_amount, price FROM book_sales INNER JOIN books ON book_sales.book_id = books.book_id WHERE books.author_id =1 

EXPLAIN из вышеперечисленного показывает мне:

 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE books ref PRIMARY,author_id author_id 4 const 3 Using index 1 SIMPLE book_sales ALL book_id NULL NULL NULL 2 Using where 

Очевидно, book_sales не использует ключ «book_id», хотя у меня он есть. Что я могу сделать, чтобы таблица book_sales использовала индекс?

Спасибо.

Редактирование производится на основе предложений (но в результате они все еще не используют индекс):

 //Does not use the index in book_sales table EXPLAIN SELECT sale_amount, price FROM books, book_sales FORCE INDEX ( book_id ) WHERE book_sales.book_id = books.book_id AND books.author_id =1 //Does not use the index in book_sales table EXPLAIN SELECT sale_amount, price FROM book_sales, books WHERE books.author_id = 1 AND book_sales.book_id = books.book_id 

Как заставить таблицу book_sale с двумя строками использовать индекс? Спасибо.

Solutions Collecting From Web of "php & mySQL: запрос не использует индекс в соединении таблицы"

Как вы можете видеть в EXPLAIN, «book_id» отображается как возможный ключ. Если MySQL не использует его, просто оптимизатор не считает, что это ускорит запрос. Это верно, если «book_sales» имеет только 2 строки, и 100% этих строк имеют один и тот же «book_id». Это называется мощностями кстати. Как избежать сканирования таблиц (руководство по MySQL)

Попробуйте заполнить его большим количеством строк, и вы увидите, что MySQL будет использовать индекс для соединения.

Изменить: запрос

 SELECT sale_amount, price FROM books, book_sales FORCE INDEX ( book_id ) WHERE book_sales.book_id = books.book_id AND books.author_id =1 

… в этом случае не будет работать, потому что оптимизатор все еще признает, что чтение индекса является субоптимальным и переключает порядок таблиц, чтобы этого не было. Вы можете форсировать порядок таблиц, используя STRAIGHT_JOIN . Это, однако, немного хак, потому что он заставляет MySQL выполнять запрос таким образом, который не самый лучший.

  EXPLAIN SELECT sale_amount, price FROM books STRAIGHT_JOIN book_sales FORCE INDEX (book_id) ON book_sales.book_id = books.book_id WHERE books.author_id = 1 

Попробуй это

 SELECT sale_amount, price FROM book_sales,books LEFT JOIN books ON(book_sales.book_id = books.book_id) WHERE books.author_id =1