MySQL查询在重复时运行较慢

MySQL查询在重复时运行较慢,mysql,geolocation,query-performance,Mysql,Geolocation,Query Performance,下面的查询(我没有写)基于50000个记录表中的距离计算进行搜索。我第一次运行它(在phpMyAdmin中)时,它的运行时间不到0.25秒。如果我立即再次运行它,则需要30秒以上的时间。我尝试添加SQL\u NO\u缓存,但没有效果。由于在生产环境中,同一查询可以在短时间内多次运行,因此这是一个主要问题 请注意,如果用户在搜索页面上选择其他条件(关键字),这需要在其中执行字符串搜索的联接表,那么问题就会消失;我假设先进行文本搜索,这样距离计算就更少了。(这就是主键上有GROUP BY的原因;这些

下面的查询(我没有写)基于50000个记录表中的距离计算进行搜索。我第一次运行它(在phpMyAdmin中)时,它的运行时间不到0.25秒。如果我立即再次运行它,则需要30秒以上的时间。我尝试添加
SQL\u NO\u缓存
,但没有效果。由于在生产环境中,同一查询可以在短时间内多次运行,因此这是一个主要问题

请注意,如果用户在搜索页面上选择其他条件(关键字),这需要在其中执行字符串搜索的联接表,那么问题就会消失;我假设先进行文本搜索,这样距离计算就更少了。(这就是主键上有GROUP BY的原因;这些扩展搜索可以生成PK的多个实例。)

还要注意的是,在我的本地测试系统上,无论我重新运行查询多少次,查询都会在0.02秒内运行

以下是查询(从实际搜索页面生成的示例):

下面是创建表:

CREATE TABLE `cc6177_clients` (
 `b1e39c_client_id` int(11) NOT NULL AUTO_INCREMENT,
 `b1e39c_client_type` enum('client','provider') COLLATE utf8_unicode_ci NOT NULL,
 `b1e39c_client_login_type` enum('normal','social') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'normal',
 `b1e39c_client_oauth_provider` enum('facebook','gplus') COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_oauth_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_access_token` text COLLATE utf8_unicode_ci,
 `b1e39c_client_referrer_key` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_nickname` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `b1e39c_client_first_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_last_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_picture` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_country_code` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_contact_number` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_address` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_lat` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_long` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_city` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_state` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_postal_code` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_status` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1' COMMENT '0=>Not Active,1=>Active',
 `b1e39c_client_activation_key` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'It is used for account activation or reset password request key',
 `b1e39c_client_verified` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0' COMMENT 'It is used to verify client email address(0=>not Verified,1=>Verified)',
 `b1e39c_client_registered_on` datetime NOT NULL,
 `b1e39c_client_login_failed_count` int(2) NOT NULL,
 `b1e39c_client_login_failed_time` datetime DEFAULT NULL,
 `b1e39c_client_login_ip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_last_login` datetime DEFAULT NULL,
 `b1e39c_client_view_status` enum('0','1') COLLATE utf8_unicode_ci NOT NULL,
 `b1e39c_client_delete_status` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1' COMMENT '0=>client deleted, 1=> client active',
 `b1e39c_client_verify_email_link_exp` datetime DEFAULT NULL,
 `b1e39c_client_company_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_website_address` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_company_logo` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Provider Company Logo',
 `b1e39c_client_desc` text COLLATE utf8_unicode_ci,
 `b1e39c_client_category_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `b1e39c_client_sub_category_id` int(11) DEFAULT NULL,
 `b1e39c_client_claim_option` enum('0','1','2') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0' COMMENT '0=>default,1=>User Added By Admin,2=>claim then make main provider',
 `b1e39c_client_membership_id` int(11) DEFAULT NULL COMMENT 'client current membership table unique id',
 `b1e39c_client_cur_membership_id` int(11) DEFAULT NULL COMMENT 'client currency membership',
 `b1e39c_client_membership_type` enum('free','paid') COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'client membership type',
 `b1e39c_client_profile_status` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
 `b1e39c_client_profile_cover` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 PRIMARY KEY (`b1e39c_client_id`),
 UNIQUE KEY `client_email` (`b1e39c_client_email`),
 KEY `client_company_name` (`b1e39c_client_company_name`),
 KEY `main_search` (`b1e39c_client_status`,`b1e39c_client_profile_status`,`b1e39c_client_type`)
) ENGINE=InnoDB AUTO_INCREMENT=55931 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
不要到处使用
VARCHAR(255)
;使用合理的限制。(这将有助于提高当前所需临时表的性能

WHERE
子句中使用一个“边界框”,加上
INDEX(lat)、INDEX(long)
(见下文)

不要用一个固定前缀(
b1e39c\u客户机
)把SQL弄得乱七八糟(这是人类的事情)

摆脱
分组方式
;它只会减慢查询速度,而不会给查询添加任何内容。(这样可以消除不必要的数据传递。)

所有这些都不能解释为什么第一次跑比下一次跑快得多

“边界框”类似于

 AND lat  BETWEEN .. AND ..
 AND long BETWEEN .. AND ..
填写的值与源lat/long的距离为50个单位。(注意,对于
long
测试,需要除以cosd(lat)

这将使查询速度提高一个数量级,从而使查询速度如此之快,以至于原始问题变得毫无意义

如果没有边界框,这可能会有帮助:

INDEX(status, profile_status, type,   -- in any order
      company_name)   -- last

如果您想继续原来的问题,请查看是否可以获得
EXPLAIN SELECT…
以显示两个不同的输出。

您是否尝试使用EXPLAIN解决此问题?A
show create table cc6177\u clients
dump可能有助于回答您的问题-服务器版本
SELECT version()
关于“用户选择其他条件”。如何?您没有给我们提供足够的信息来帮助您。请阅读以下内容:请特别注意有关查询性能的部分。然后请回答您的问题。
按b1e39c_client_id分组
-您是否按主键分组?这毫无意义。常量前缀和所有内容都是varchar(255)不幸的是,当我继承该项目时,我就在那里,但我希望尽可能地清理。
 AND lat  BETWEEN .. AND ..
 AND long BETWEEN .. AND ..
INDEX(status, profile_status, type,   -- in any order
      company_name)   -- last