【发布时间】:2014-05-31 02:12:56
【问题描述】:
以下 sn-p 代码取自我的 global.class.php 文件。当搜索“类型”等于“邮政编码”或“零件编号”时,我目前遇到执行 SQL 查询所需时间的问题。请参阅下面的 sn-p 以了解包括处理时间在内的说明。
function findOrder($type, $query) {
$db = new db;
$tasks = new tasks;
if($type == 'order-id') {
return $db->query("
SELECT details.id, details.order_id, users.title, users.first_name, users.last_name, details.date_time, details.status
FROM orders_details AS details
LEFT JOIN orders_users AS users
ON users.order_id = details.order_id
WHERE details.order_id LIKE '$query'
ORDER BY id DESC
");
} elseif($type == 'postcode') {
return $db->query("
SELECT addresses.id AS id, addresses.order_id, addresses.postcode, users.title, users.first_name, users.last_name, details.date_time, details.status
FROM orders_users as users
LEFT JOIN orders_details as details
ON users.order_id = details.order_id
LEFT JOIN orders_addresses as addresses
ON addresses.order_id = details.order_id
WHERE REPLACE(addresses.postcode, ' ','') LIKE '$query'
ORDER BY id DESC
");
} elseif($type == 'surname') {
return $db->query("
SELECT users.id AS id, users.order_id, users.title, users.first_name, users.last_name, details.date_time, details.status
FROM orders_users AS users
LEFT JOIN orders_details AS details
ON users.order_id = details.order_id
WHERE REPLACE(users.last_name, ' ','') LIKE '$query'
ORDER BY id DESC
");
} elseif($type == 'part-number') {
$query = $tasks->getProductID($query); //Change $query to product ID
return $db->query("
SELECT carts.id AS id, carts.order_id, carts.product_id, users.title, users.first_name, users.last_name, details.date_time, details.status
FROM orders_users AS users
LEFT JOIN orders_details AS details
ON users.order_id = details.order_id
LEFT JOIN orders_carts AS carts
ON carts.order_id = details.order_id
WHERE carts.product_id = '$query'
ORDER BY id DESC
");
}
}
请看下面的执行时间:
type = order-id
query = 106696 //(1 result returned)
page time = 0.0074
sql time = 0.0065
type = surname
query = smith //(23 results returned)
page time = 0.0725
sql time = 0.0700
type = postcode
query = **hidden** //(1 result returned)
page time = 2.6505
sql time = 0.0125
type = part-number
query = **hidden** //(13 results returned)
page time = 2.8564 //(I also checked the getProductID() function, and this takes 0.0123)
sql time = 0.0470
页面时间是调用 findOrder('type', 'query'); 所花费的时间
SQL 时间是我直接在 phpMyAdmin 中重复查询所用的时间。
我可以看到订单 ID 和姓氏查询与邮政编码和零件号查询之间的唯一区别是有一个额外的 LEFT JOIN。这并不能解释为什么在 phpMyAdmin 中执行的相同查询返回得如此之快。我不知道为什么要花将近 3 秒才能返回一个应该花费不到 50 毫秒的查询。
其他人能明白为什么会这样吗?如果你还需要什么,请告诉我。
按要求解释查询
订单号:
id select_type table type possible_keys key key_len ref rows Extra
1 简单细节 ALL NULL NULL NULL NULL 1975 使用 where;使用临时的;使用文件排序
1 简单用户 ALL NULL NULL NULL NULL 1992
姓氏:
1 SIMPLE 用户 ALL NULL NULL NULL NULL 1992 使用 where;使用临时的;使用文件排序
1 简单的细节 ALL NULL NULL NULL NULL 1975
邮编:
1 简单细节 ALL NULL NULL NULL NULL 1966 使用临时;使用文件排序
1 SIMPLE 用户 ALL NULL NULL NULL NULL 1983 使用 where;使用连接缓冲区
1 简单地址 ALL NULL NULL NULL NULL 1983 使用 where;使用连接缓冲区
零件编号:
1 简单细节 ALL NULL NULL NULL NULL 1975 使用临时;使用文件排序
1 SIMPLE 用户 ALL NULL NULL NULL NULL 1992 使用 where;使用连接缓冲区
1 SIMPLE carts ALL NULL NULL NULL NULL 3611 使用where;使用连接缓冲区
根据要求创建表查询
--
-- Table structure for table `orders_addresses`
--
CREATE TABLE IF NOT EXISTS `orders_addresses` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` varchar(255) NOT NULL,
`active` tinyint(4) NOT NULL,
`company` varchar(255) NOT NULL,
`line1` varchar(255) NOT NULL,
`line2` varchar(255) NOT NULL,
`line3` varchar(255) NOT NULL,
`town` varchar(255) NOT NULL,
`county` varchar(255) NOT NULL,
`postcode` varchar(255) NOT NULL,
`country` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2004 ;
-- --------------------------------------------------------
--
-- Table structure for table `orders_carts`
--
CREATE TABLE IF NOT EXISTS `orders_carts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` varchar(255) NOT NULL,
`product_id` int(11) NOT NULL,
`part_name` varchar(255) NOT NULL,
`qty_ord` int(11) NOT NULL,
`qty_rcv` int(11) NOT NULL,
`cost_net` int(11) NOT NULL,
`cost_gross` int(11) NOT NULL,
`status` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3629 ;
-- --------------------------------------------------------
--
-- Table structure for table `orders_details`
--
CREATE TABLE IF NOT EXISTS `orders_details` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` varchar(255) NOT NULL,
`transaction_id` varchar(255) NOT NULL,
`date_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`postage` int(11) NOT NULL,
`sub_total` int(11) NOT NULL,
`cart_vat` int(11) NOT NULL,
`total` int(11) NOT NULL,
`status` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1985 ;
-- --------------------------------------------------------
--
-- Table structure for table `orders_users`
--
CREATE TABLE IF NOT EXISTS `orders_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` varchar(255) NOT NULL,
`active` tinyint(4) NOT NULL,
`title` varchar(255) NOT NULL,
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`telephone` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2005 ;
【问题讨论】:
-
显示
EXPLAIN query输出的内容,还添加了一些带有索引的表定义。 phpMyAdmin 是否默认添加LIMIT?尝试使用mysql客户端并执行这些查询。不要在 phpmyadmin 中测量它。 -
我已经添加了您要求的解释查询输出,我将登录到服务器并在我有几分钟空闲时通过 mysql 执行这些查询。
-
您能否附上
CREATE TABLE对这些表的查询? -
我已经添加了 CREATE TABLE 查询。
标签: php mysql phpmyadmin