php &

2 Cevap php

Belirli bir kitap yazar için tüm book_sales bilgilerini listelemek için çalışıyorum. Yani bir sorgu var ve kayıtları arama için dizini kullanarak değil.

The following is my tables structure:

-- 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);

My Query:

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

An EXPLAIN on the above, shows me:

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

Bunu olmasına rağmen açıkça book_sales, anahtar 'book_id' kullanarak değil. Ne book_sales tablo Endeksi kullanmak yapmak için ne yapabilirim?

Teşekkür ederim.

Edits done based on suggestions (but the result is they still do not use index):

//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

Indeksi kullanmak, sadece 2 satır ile book_sale tabloyu zorlamak nasıl? Teşekkür ederim.

2 Cevap

Eğer EXPLAIN de görebileceğiniz gibi, "book_id" olası bir anahtar olarak listelenir. MySQL kullanmak değilse, bu iyileştirici sorguyu hızlandırmak olacağını düşünmek değil sadece. "Book_sales" sadece 2 satır vardır, ve bu satırların% 100 aynı "book_id" paylaşmak durumunda hangisi doğrudur. Bu btw önem düzeyi denir. How to Avoid Table Scans (MySQL Manuel)

Daha fazla satır ile doldurarak deneyin ve MySQL katılmak için bir dizin kullanmak olacağını görmek gerekir.

Edit: Sorgu

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

Optimizer hala endeksi okuyarak suboptimaldir ve bunu yaparken önlemek için masa düzeni geçer tanır çünkü ... bu durumda da işe yaramaz. Sen STRAIGHT_JOIN kullanarak tablo sırasını zorlayabilir. Bu, ancak, kesmek biraz da iyi olmayan bir şekilde sorguyu yürütmek için MySQL zorlar çünkü.

      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

Bu deneyin

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