最有效的数据收集方式?
让我们首先对我的情况进行一个重要说明:
- 我的 MySQL 数据库中有 1 个表,其中包含大约 10,000 个条目。
目前,当从表 #1 收集信息时。我每页总共收集 20 - 24 行。
示例为:
Q1 : SELECT * FROM table WHERE cat = 1 LIMIT 0,25 R1:id:1,name:something,info:12
执行这些查询的 PHP 文件由 jquery ajax 函数调用,并创建一个由 jquery 函数读取并向用户显示的 XML 文件。
我的问题是。我如何提高速度和速度?该过程的稳定性。我可以让多达 1 万名访问者同时获取信息,这使得我的服务器变得极其缓慢,在某些情况下甚至崩溃。
我几乎不知道,所以我在这里寻求帮助。这是我当前数据收集的实际演示(:
public function collectItems($type, $genre, $page = 0, $search = 0)
{
// Call Core (Necessary for Database Interaction
global $plusTG;
// If Search
if($search)
{
$searchString = ' AND (name LIKE "%'.$search.'%")';
}
else
{
$searchString = '';
}
// Validate Query
$search = $plusTG->validateQuery($search);
$type = $plusTG->validateQuery($type);
$genre = $plusTG->validateQuery($genre);
// Check Numeric
if((!is_numeric($genre)))
{
return false;
}
else
{
if(!is_numeric($type))
{
if($type != 0)
{
$typeSelect = '';
$split = explode(',',$type);
foreach($split as $oneType)
{
if($typeSelect == '')
{
$typeSelect .= 'type = '.$oneType.' ';
}
else
{
$typeSelect .= 'OR type = '.$oneType.' ';
}
}
}
}
else
{
$typeSelect = 'type = ' . $type . ' ';
}
//echo $typeSelect;
$limit = ($page - 1) * 20;
if(($type != 0) && ($genre != 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND genre = '.$genre.' AND ('.$typeSelect.')'.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND genre = '.$genre.' AND ('.$typeSelect.')'.$searchString);
}
elseif(($type == 0) && ($genre != 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND genre = '.$genre.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND genre = '.$genre.$searchString);
}
elseif(($type != 0) && ($genre == 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND ('.$typeSelect.')'.$searchString.'ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND ('.$typeSelect.')'.$searchString);
}
elseif(($type == 0) && ($genre == 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1'.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1'.$searchString);
}
$this->buildInfo($items->num_rows, $total->fetch_assoc());
while($singleItem = $items->fetch_assoc())
{
$this->addItem($singleItem);
}
}
return true;
}
构建信息调用和添加项目调用将项目添加到 DOMXML。
这是我的 javascript(域和文件名已过滤):
function itemRequest(type,genre,page, search)
{
if(ajaxReady != 0)
{
ajaxReady = 0;
$('#item_container').text('');
var searchUrl = '';
var searchLink;
var ajaxURL;
if(search != 0)
{
searchUrl = '&search=' + search;
searchLink = search;
ajaxURL = "/////file.php";
}
else
{
searchLink = 0;
ajaxURL = "////file.php";
}
$.ajax({
type: "GET",
url: ajaxURL,
data: "spec=1&type="+type+"&genre="+genre+"&page="+page+searchUrl,
success: function(itemListing){
$(itemListing).find('info').each(function()
{
var total = $(this).find('total').text();
updatePaging(total, page, type, genre, searchLink);
});
var items = $(itemListing).find('items');
$(items).find('item').each(function()
{
var itemId = $(this).find('id').text();
var itemType = $(this).find('type').text();
var itemGenre = $(this).find('genre').text();
var itemTmId = $(this).find('tm').text();
var itemName = $(this).find('name').text();
buildItem(itemId, itemType, itemGenre, itemTmId, itemName);
});
$('.item_one img[title]').tooltip();
},
complete: function(){
ajaxReady = 1;
}
});
}
构建项目调用此:
function buildItem(itemId, itemType, itemGenre, itemTmId, itemName)
{
// Pick up Misc. Data
var typeName = nameOfType(itemType);
// Create Core Object
var anItem = $('<div/>', {
'class':'item_one'
});
// Create Item Image
$('<img/>', {
'src':'///'+typeName+'_'+itemTmId+'_abc.png',
'alt':itemName,
'title':itemName,
click:function(){
eval(typeName + 'Type = ' + itemTmId);
$('.equipped_item[name='+typeName+']').attr('src','//'+typeName+'_'+itemTmId+'_abc.png');
$('.equipped_item[name='+typeName+']').attr('alt',itemName);
$('.equipped_item[name='+typeName+']').attr('title',itemName);
$('.equipped_item[title]').tooltip();
recentEquipped(typeName, itemTmId, itemName);
updateSelfy();
}
}).appendTo(anItem);
// Favs
var arrayHack = false;
$(favEquips).each(function(){
if(arrayHack == false)
{
if(in_array(itemTmId, this))
{
arrayHack = true;
}
}
});
var itemFaved = '';
if(arrayHack == true)
{
itemFaved = 'activated';
}
$('<div/>',{
'class':'fav',
'id':itemFaved,
click:function(){
if($(this).attr('id') != 'activated')
{
$(this).attr('id','activated');
}
else
{
$(this).removeAttr('id');
}
itemFav(itemTmId, typeName, itemName);
}
}).appendTo(anItem);
$(anItem).appendTo('#item_container');
}
如果有人可以帮助我改进这段代码,我们将非常感激。
Let's first get to an important note about my situation:
- I have 1 table in my MySQL database with approx 10 thousand entries
Currently, when collecting information from table #1. I collect a total of 20 - 24 rows per page.
Example being:
Q1 : SELECT * FROM table WHERE cat = 1 LIMIT 0,25
R1: id: 1, name: something, info: 12
The PHP file that does these queries, is called by the jquery ajax function, and creates an XML file that that jquery function reads and shows to the user.
My question here is. How do i improve the speed & stability of this process. I can have up to 10 thousand visitors picking up information at the same time, which makes my server go extremely sluggish and in some cases even crash.
I'm pretty much out of idea's, so i'm asking for help here. Here's an actual presentation of my current data collection (:
public function collectItems($type, $genre, $page = 0, $search = 0)
{
// Call Core (Necessary for Database Interaction
global $plusTG;
// If Search
if($search)
{
$searchString = ' AND (name LIKE "%'.$search.'%")';
}
else
{
$searchString = '';
}
// Validate Query
$search = $plusTG->validateQuery($search);
$type = $plusTG->validateQuery($type);
$genre = $plusTG->validateQuery($genre);
// Check Numeric
if((!is_numeric($genre)))
{
return false;
}
else
{
if(!is_numeric($type))
{
if($type != 0)
{
$typeSelect = '';
$split = explode(',',$type);
foreach($split as $oneType)
{
if($typeSelect == '')
{
$typeSelect .= 'type = '.$oneType.' ';
}
else
{
$typeSelect .= 'OR type = '.$oneType.' ';
}
}
}
}
else
{
$typeSelect = 'type = ' . $type . ' ';
}
//echo $typeSelect;
$limit = ($page - 1) * 20;
if(($type != 0) && ($genre != 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND genre = '.$genre.' AND ('.$typeSelect.')'.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND genre = '.$genre.' AND ('.$typeSelect.')'.$searchString);
}
elseif(($type == 0) && ($genre != 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND genre = '.$genre.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND genre = '.$genre.$searchString);
}
elseif(($type != 0) && ($genre == 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND ('.$typeSelect.')'.$searchString.'ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND ('.$typeSelect.')'.$searchString);
}
elseif(($type == 0) && ($genre == 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1'.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1'.$searchString);
}
$this->buildInfo($items->num_rows, $total->fetch_assoc());
while($singleItem = $items->fetch_assoc())
{
$this->addItem($singleItem);
}
}
return true;
}
The build info call & add item call are adding the items to the DOMXML.
This is my javascript (domain and filename filtered):
function itemRequest(type,genre,page, search)
{
if(ajaxReady != 0)
{
ajaxReady = 0;
$('#item_container').text('');
var searchUrl = '';
var searchLink;
var ajaxURL;
if(search != 0)
{
searchUrl = '&search=' + search;
searchLink = search;
ajaxURL = "/////file.php";
}
else
{
searchLink = 0;
ajaxURL = "////file.php";
}
$.ajax({
type: "GET",
url: ajaxURL,
data: "spec=1&type="+type+"&genre="+genre+"&page="+page+searchUrl,
success: function(itemListing){
$(itemListing).find('info').each(function()
{
var total = $(this).find('total').text();
updatePaging(total, page, type, genre, searchLink);
});
var items = $(itemListing).find('items');
$(items).find('item').each(function()
{
var itemId = $(this).find('id').text();
var itemType = $(this).find('type').text();
var itemGenre = $(this).find('genre').text();
var itemTmId = $(this).find('tm').text();
var itemName = $(this).find('name').text();
buildItem(itemId, itemType, itemGenre, itemTmId, itemName);
});
$('.item_one img[title]').tooltip();
},
complete: function(){
ajaxReady = 1;
}
});
}
Build item calls this:
function buildItem(itemId, itemType, itemGenre, itemTmId, itemName)
{
// Pick up Misc. Data
var typeName = nameOfType(itemType);
// Create Core Object
var anItem = $('<div/>', {
'class':'item_one'
});
// Create Item Image
$('<img/>', {
'src':'///'+typeName+'_'+itemTmId+'_abc.png',
'alt':itemName,
'title':itemName,
click:function(){
eval(typeName + 'Type = ' + itemTmId);
$('.equipped_item[name='+typeName+']').attr('src','//'+typeName+'_'+itemTmId+'_abc.png');
$('.equipped_item[name='+typeName+']').attr('alt',itemName);
$('.equipped_item[name='+typeName+']').attr('title',itemName);
$('.equipped_item[title]').tooltip();
recentEquipped(typeName, itemTmId, itemName);
updateSelfy();
}
}).appendTo(anItem);
// Favs
var arrayHack = false;
$(favEquips).each(function(){
if(arrayHack == false)
{
if(in_array(itemTmId, this))
{
arrayHack = true;
}
}
});
var itemFaved = '';
if(arrayHack == true)
{
itemFaved = 'activated';
}
$('<div/>',{
'class':'fav',
'id':itemFaved,
click:function(){
if($(this).attr('id') != 'activated')
{
$(this).attr('id','activated');
}
else
{
$(this).removeAttr('id');
}
itemFav(itemTmId, typeName, itemName);
}
}).appendTo(anItem);
$(anItem).appendTo('#item_container');
}
If anyone could help me improve this code, it'd be very much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
cat
列的索引cat
column我同意 Zepplock 的观点,找出瓶颈在哪里很重要 - 如果不是,你只是猜测。 Zepplock 的列表很好,但我还要添加缓存:
查找瓶颈。
有很多意见和方法可以做到这一点...基本上,当您的站点处于负载状态时,获取完成该过程中每个步骤所需的时间:数据库查询、服务器端进程、客户端进程。
使用索引。
如果您的数据库速度很慢,您很可能可以通过优化查询来获得很大的改进。表索引可能是有序的...使用“EXPLAIN”来帮助确定索引应放置在何处以优化查询:(
我打赌索引位于
active
和name
就可以了)还要尽量避免使用通配符“*”。相反,只询问您需要的列。类似于:
缓存您的结果。
如果数据库中的记录没有更改,则没有理由尝试重新查询结果。使用某种缓存来减少数据库的负载(memcached、平面文件等)。根据您使用的数据库类/实用程序,它可能已经能够缓存结果。
I agree with Zepplock, it is important to find out where the bottleneck is - if not, you're only guessing. Zepplock's list is good but I would also add caching:
Find the Bottleneck.
There are number opinions and ways to do this... Basically when your site is under load, get the time it takes to complete each step in the process: The DB queries, the server-side processes, the client side processes.
Use Indexes.
If your DB is slow chances are you can get a lot of improvement by optimizing your queries. A table index may be in order... Use 'EXPLAIN' to help identify where indexes should be placed to optimize your queries:
(I bet an index on
active
andname
would do the trick)Also try to avoid using the wildcard '*'. Instead only ask for the columns you need. Something like:
Cache Your Results.
If the records in the DB have not changed then there is no reason to try an re-query the results. Use some sort of caching to reduce the load on your DB (memcached, flat file, etc..). Depending on the database class / utilities you're using it may already be capable of caching results.