Skip to content
Server
2014.09.13 09:13

XE DB 튜닝

조회 수 4377 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄



COUNT 로그 캐시하기

참고 : www.xpressengine.com/forum/20712872


C:\APM_Setup\htdocs\classes\db\DBMysql.class.php


 


<?php

/* Copyright (C) NAVER <http://www.navercorp.com> */


/**

 * Class to use MySQL DBMS

 * mysql handling class

 *

 * Does not use prepared statements, since mysql driver does not support them

 *

 * @author NAVER (developers@xpressengine.com)

 * @package /classes/db

 * @version 0.1

 */

class DBMysql extends DB

{


/**

* prefix of a tablename (One or more XEs can be installed in a single DB)

* @var string

*/

var $prefix = 'xe_'; // / <

var $comment_syntax = '/* %s */';


/**

* Column type used in MySQL

*

* Becasue a common column type in schema/query xml is used for colum_type,

* it should be replaced properly for each DBMS

* @var array

*/

var $column_type = array(

'bignumber' => 'bigint',

'number' => 'bigint',

'varchar' => 'varchar',

'char' => 'char',

'text' => 'text',

'bigtext' => 'longtext',

'date' => 'varchar(14)',

'float' => 'float',

);


/**

* Constructor

* @return void

*/

function DBMysql()

{

$this->_setDBInfo();

$this->_connect();

}


/**

* Create an instance of this class

* @return DBMysql return DBMysql object instance

*/

function create()

{

return new DBMysql;

}


/**

* DB Connect

* this method is private

* @param array $connection connection's value is db_hostname, db_port, db_database, db_userid, db_password

* @return resource

*/

function __connect($connection)

{

// Ignore if no DB information exists

if(strpos($connection["db_hostname"], ':') === false && $connection["db_port"])

{

$connection["db_hostname"] .= ':' . $connection["db_port"];

}


// Attempt to connect

$result = @mysql_connect($connection["db_hostname"], $connection["db_userid"], $connection["db_password"]);

if(!$result)

{

exit('XE cannot connect to DB.');

}


if(mysql_error())

{

$this->setError(mysql_errno(), mysql_error());

return;

}

// Error appears if the version is lower than 4.1

if(version_compare(mysql_get_server_info($result), '4.1', '<'))

{

$this->setError(-1, 'XE cannot be installed under the version of mysql 4.1. Current mysql version is ' . mysql_get_server_info());

return;

}

// select db

@mysql_select_db($connection["db_database"], $result);

if(mysql_error())

{

$this->setError(mysql_errno(), mysql_error());

return;

}


return $result;

}


/**

* If have a task after connection, add a taks in this method

* this method is private

* @param resource $connection

* @return void

*/

function _afterConnect($connection)

{

// Set utf8 if a database is MySQL

$this->_query("set names 'utf8'", $connection);

}


/**

* DB disconnection

* this method is private

* @param resource $connection

* @return void

*/

function _close($connection)

{

@mysql_close($connection);

}


/**

* Handles quatation of the string variables from the query

* @param string $string

* @return string

*/

function addQuotes($string)

{

if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc())

{

$string = stripslashes(str_replace("\\", "\\\\", $string));

}

if(!is_numeric($string))

{

$string = @mysql_real_escape_string($string);

}

return $string;

}


/**

* DB transaction start

* this method is private

* @return boolean

*/

function _begin()

{

return true;

}


/**

* DB transaction rollback

* this method is private

* @return boolean

*/

function _rollback()

{

return true;

}


/**

* DB transaction commit

* this method is private

* @return boolean

*/

function _commit()

{

return true;

}


/**

* Execute the query

* this method is private

* @param string $query

* @param resource $connection

* @return resource

*/

function __query($query, $connection)

{

if(!$connection)

{

exit('XE cannot handle DB connection.');

}

// Run the query statement

$result = mysql_query($query, $connection);

// Error Check

if(mysql_error($connection))

{

$this->setError(mysql_errno($connection), mysql_error($connection));

}

// Return result

return $result;

}


/**

* Fetch the result

* @param resource $result

* @param int|NULL $arrayIndexEndValue

* @return array

*/

function _fetch($result, $arrayIndexEndValue = NULL)

{

$output = array();

if(!$this->isConnected() || $this->isError() || !$result)

{

return $output;

}

while($tmp = $this->db_fetch_object($result))

{

if($arrayIndexEndValue)

{

$output[$arrayIndexEndValue--] = $tmp;

}

else

{

$output[] = $tmp;

}

}

if(count($output) == 1)

{

if(isset($arrayIndexEndValue))

{

return $output;

}

else

{

return $output[0];

}

}

$this->db_free_result($result);

return $output;

}


/**

* Return the sequence value incremented by 1

* Auto_increment column only used in the sequence table

* @return int

*/

function getNextSequence()

{

$query = sprintf("insert into `%ssequence` (seq) values ('0')", $this->prefix);

$this->_query($query);

$sequence = $this->db_insert_id();

if($sequence % 10000 == 0)

{

$query = sprintf("delete from  `%ssequence` where seq < %d", $this->prefix, $sequence);

$this->_query($query);

}


return $sequence;

}


/**

* Function to obtain mysql old password(mysql only)

* @param string $password input password

* @param string $saved_password saved password in DBMS

* @return boolean

*/

function isValidOldPassword($password, $saved_password)

{

$query = sprintf("select password('%s') as password, old_password('%s') as old_password", $this->addQuotes($password), $this->addQuotes($password));

$result = $this->_query($query);

$tmp = $this->_fetch($result);

if($tmp->password == $saved_password || $tmp->old_password == $saved_password)

{

return true;

}

return false;

}


/**

* Check a table exists status

* @param string $target_name

* @return boolean

*/

function isTableExists($target_name)

{

$query = sprintf("show tables like '%s%s'", $this->prefix, $this->addQuotes($target_name));

$result = $this->_query($query);

$tmp = $this->_fetch($result);

if(!$tmp)

{

return false;

}

return true;

}


/**

* Add a column to the table

* @param string $table_name table name

* @param string $column_name column name

* @param string $type column type, default value is 'number'

* @param int $size column size

* @param string|int $default default value

* @param boolean $notnull not null status, default value is false

* @return void

*/

function addColumn($table_name, $column_name, $type = 'number', $size = '', $default = '', $notnull = false)

{

$type = $this->column_type[$type];

if(strtoupper($type) == 'INTEGER')

{

$size = '';

}


$query = sprintf("alter table `%s%s` add `%s` ", $this->prefix, $table_name, $column_name);

if($size)

{

$query .= sprintf(" %s(%s) ", $type, $size);

}

else

{

$query .= sprintf(" %s ", $type);

}

if($default)

{

$query .= sprintf(" default '%s' ", $default);

}

if($notnull)

{

$query .= " not null ";

}


return $this->_query($query);

}


/**

* Drop a column from the table

* @param string $table_name table name

* @param string $column_name column name

* @return void

*/

function dropColumn($table_name, $column_name)

{

$query = sprintf("alter table `%s%s` drop `%s` ", $this->prefix, $table_name, $column_name);

$this->_query($query);

}


/**

* Check column exist status of the table

* @param string $table_name table name

* @param string $column_name column name

* @return boolean

*/

function isColumnExists($table_name, $column_name)

{

$query = sprintf("show fields from `%s%s`", $this->prefix, $table_name);

$result = $this->_query($query);

if($this->isError())

{

return;

}

$output = $this->_fetch($result);

if($output)

{

$column_name = strtolower($column_name);

foreach($output as $key => $val)

{

$name = strtolower($val->Field);

if($column_name == $name)

{

return true;

}

}

}

return false;

}


/**

* Add an index to the table

* $target_columns = array(col1, col2)

* $is_unique? unique : none

* @param string $table_name table name

* @param string $index_name index name

* @param string|array $target_columns target column or columns

* @param boolean $is_unique

* @return void

*/

function addIndex($table_name, $index_name, $target_columns, $is_unique = false)

{

if(!is_array($target_columns))

{

$target_columns = array($target_columns);

}


$query = sprintf("alter table `%s%s` add %s index `%s` (%s);", $this->prefix, $table_name, $is_unique ? 'unique' : '', $index_name, implode(',', $target_columns));

$this->_query($query);

}


/**

* Drop an index from the table

* @param string $table_name table name

* @param string $index_name index name

* @param boolean $is_unique

* @return void

*/

function dropIndex($table_name, $index_name, $is_unique = false)

{

$query = sprintf("alter table `%s%s` drop index `%s`", $this->prefix, $table_name, $index_name);

$this->_query($query);

}


/**

* Check index status of the table

* @param string $table_name table name

* @param string $index_name index name

* @return boolean

*/

function isIndexExists($table_name, $index_name)

{

//$query = sprintf("show indexes from %s%s where key_name = '%s' ", $this->prefix, $table_name, $index_name);

$query = sprintf("show indexes from `%s%s`", $this->prefix, $table_name);

$result = $this->_query($query);

if($this->isError())

{

return;

}

$output = $this->_fetch($result);

if(!$output)

{

return;

}

if(!is_array($output))

{

$output = array($output);

}


for($i = 0; $i < count($output); $i++)

{

if($output[$i]->Key_name == $index_name)

{

return true;

}

}

return false;

}


/**

* Creates a table by using xml contents

* @param string $xml_doc xml schema contents

* @return void|object

*/

function createTableByXml($xml_doc)

{

return $this->_createTable($xml_doc);

}


/**

* Creates a table by using xml file path

* @param string $file_name xml schema file path

* @return void|object

*/

function createTableByXmlFile($file_name)

{

if(!file_exists($file_name))

{

return;

}

// read xml file

$buff = FileHandler::readFile($file_name);

return $this->_createTable($buff);

}


/**

* Create table by using the schema xml

*

* type : number, varchar, tinytext, text, bigtext, char, date, \n

* opt : notnull, default, size\n

* index : primary key, index, unique\n

* @param string $xml_doc xml schema contents

* @return void|object

*/

function _createTable($xml_doc)

{

// xml parsing

$oXml = new XmlParser();

$xml_obj = $oXml->parse($xml_doc);

// Create a table schema

$table_name = $xml_obj->table->attrs->name;

if($this->isTableExists($table_name))

{

return;

}

$table_name = $this->prefix . $table_name;


if(!is_array($xml_obj->table->column))

{

$columns[] = $xml_obj->table->column;

}

else

{

$columns = $xml_obj->table->column;

}


$primary_list = array();

$unique_list = array();

$index_list = array();


foreach($columns as $column)

{

$name = $column->attrs->name;

$type = $column->attrs->type;

$size = $column->attrs->size;

$notnull = $column->attrs->notnull;

$primary_key = $column->attrs->primary_key;

$index = $column->attrs->index;

$unique = $column->attrs->unique;

$default = $column->attrs->default;

$auto_increment = $column->attrs->auto_increment;


$column_schema[] = sprintf('`%s` %s%s %s %s %s', $name, $this->column_type[$type], $size ? '(' . $size . ')' : '', isset($default) ? "default '" . $default . "'" : '', $notnull ? 'not null' : '', $auto_increment ? 'auto_increment' : '');


if($primary_key)

{

$primary_list[] = $name;

}

else if($unique)

{

$unique_list[$unique][] = $name;

}

else if($index)

{

$index_list[$index][] = $name;

}

}


if(count($primary_list))

{

$column_schema[] = sprintf("primary key (%s)", '`' . implode($primary_list, '`,`') . '`');

}


if(count($unique_list))

{

foreach($unique_list as $key => $val)

{

$column_schema[] = sprintf("unique %s (%s)", $key, '`' . implode($val, '`,`') . '`');

}

}


if(count($index_list))

{

foreach($index_list as $key => $val)

{

$column_schema[] = sprintf("index %s (%s)", $key, '`' . implode($val, '`,`') . '`');

}

}


$schema = sprintf('create table `%s` (%s%s) %s;', $this->addQuotes($table_name), "\n", implode($column_schema, ",\n"), "ENGINE = MYISAM  CHARACTER SET utf8 COLLATE utf8_general_ci");


$output = $this->_query($schema);

if(!$output)

return false;

}


/**

* Handles insertAct

* @param Object $queryObject

* @param boolean $with_values

* @return resource

*/

function _executeInsertAct($queryObject, $with_values = true)

{

$query = $this->getInsertSql($queryObject, $with_values, true);

$query .= (__DEBUG_QUERY__ & 1 && $this->query_id) ? sprintf(' ' . $this->comment_syntax, $this->query_id) : '';

if(is_a($query, 'Object'))

{

return;

}

return $this->_query($query);

}


/**

* Handles updateAct

* @param Object $queryObject

* @param boolean $with_values

* @return resource

*/

function _executeUpdateAct($queryObject, $with_values = true)

{

$query = $this->getUpdateSql($queryObject, $with_values, true);

if(is_a($query, 'Object'))

{

if(!$query->toBool()) return $query;

else return;

}


$query .= (__DEBUG_QUERY__ & 1 && $this->query_id) ? sprintf(' ' . $this->comment_syntax, $this->query_id) : '';



return $this->_query($query);

}


/**

* Handles deleteAct

* @param Object $queryObject

* @param boolean $with_values

* @return resource

*/

function _executeDeleteAct($queryObject, $with_values = true)

{

$query = $this->getDeleteSql($queryObject, $with_values, true);

$query .= (__DEBUG_QUERY__ & 1 && $this->query_id) ? sprintf(' ' . $this->comment_syntax, $this->query_id) : '';

if(is_a($query, 'Object'))

{

return;

}

return $this->_query($query);

}


/**

* Handle selectAct

* In order to get a list of pages easily when selecting \n

* it supports a method as navigation

* @param Object $queryObject

* @param resource $connection

* @param boolean $with_values

* @return Object

*/

function _executeSelectAct($queryObject, $connection = null, $with_values = true)

{

$limit = $queryObject->getLimit();

$result = NULL;

if($limit && $limit->isPageHandler())

{

return $this->queryPageLimit($queryObject, $result, $connection, $with_values);

}

else

{

$query = $this->getSelectSql($queryObject, $with_values);

if(is_a($query, 'Object'))

{

return;

}

$query .= (__DEBUG_QUERY__ & 1 && $queryObject->queryID) ? sprintf(' ' . $this->comment_syntax, $queryObject->queryID) : '';


$result = $this->_query($query, $connection);

if($this->isError())

{

return $this->queryError($queryObject);

}


$data = $this->_fetch($result);

$buff = new Object ();

$buff->data = $data;


if($queryObject->usesClickCount())

{

$update_query = $this->getClickCountQuery($queryObject);

$this->_executeUpdateAct($update_query, $with_values);

}


return $buff;

}

}


/**

* Get the ID generated in the last query

* Return next sequence from sequence table

* This method use only mysql

* @return int

*/

function db_insert_id()

{

$connection = $this->_getConnection('master');

return mysql_insert_id($connection);

}


/**

* Fetch a result row as an object

* @param resource $result

* @return object

*/

function db_fetch_object(&$result)

{

return mysql_fetch_object($result);

}


/**

* Free result memory

* @param resource $result

* @return boolean Returns TRUE on success or FALSE on failure.

*/

function db_free_result(&$result)

{

return mysql_free_result($result);

}


/**

* Return the DBParser

* @param boolean $force

* @return DBParser

*/

function &getParser($force = FALSE)

{

$dbParser = new DBParser('`', '`', $this->prefix);

return $dbParser;

}


/**

* If have a error, return error object

* @param Object $queryObject

* @return Object

*/

function queryError($queryObject)

{

$limit = $queryObject->getLimit();

if($limit && $limit->isPageHandler())

{

$buff = new Object ();

$buff->total_count = 0;

$buff->total_page = 0;

$buff->page = 1;

$buff->data = array();

$buff->page_navigation = new PageHandler(/* $total_count */0, /* $total_page */1, /* $page */1, /* $page_count */10); //default page handler values

return $buff;

}

else

{

return;

}

}


/**

* If select query execute, return page info

* @param Object $queryObject

* @param resource $result

* @param resource $connection

* @param boolean $with_values

* @return Object Object with page info containing

*/

function queryPageLimit($queryObject, $result, $connection, $with_values = true)

{

$limit = $queryObject->getLimit();

// Total count

$temp_where = $queryObject->getWhereString($with_values, false);

$count_query = sprintf('select count(*) as "count" %s %s', 'FROM ' . $queryObject->getFromString($with_values), ($temp_where === '' ? '' : ' WHERE ' . $temp_where));


// Check for distinct query and if found update count query structure

$temp_select = $queryObject->getSelectString($with_values);

$uses_distinct = stripos($temp_select, "distinct") !== false;

$uses_groupby = $queryObject->getGroupByString() != '';

if($uses_distinct || $uses_groupby)

{

$count_query = sprintf('select %s %s %s %s'

, $temp_select == '*' ? '1' : $temp_select

, 'FROM ' . $queryObject->getFromString($with_values)

, ($temp_where === '' ? '' : ' WHERE ' . $temp_where)

, ($uses_groupby ? ' GROUP BY ' . $queryObject->getGroupByString() : '')

);


// If query uses grouping or distinct, count from original select

$count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query);

}


$count_query .= (__DEBUG_QUERY__ & 1 && $queryObject->queryID) ? sprintf(' ' . $this->comment_syntax, $queryObject->queryID) : '';

$result_count = $this->_query($count_query, $connection);

$count_output = $this->_fetch($result_count);

$total_count = (int) (isset($count_output->count) ? $count_output->count : NULL);


$list_count = $limit->list_count->getValue();

if(!$list_count)

{

$list_count = 20;

}

$page_count = $limit->page_count->getValue();

if(!$page_count)

{

$page_count = 10;

}

$page = $limit->page->getValue();

if(!$page || $page < 1)

{

$page = 1;

}


// total pages

if($total_count)

{

$total_page = (int) (($total_count - 1) / $list_count) + 1;

}

else

{

$total_page = 1;

}


// check the page variables

if($page > $total_page)

{

// If requested page is bigger than total number of pages, return empty list

$buff = new Object ();

$buff->total_count = $total_count;

$buff->total_page = $total_page;

$buff->page = $page;

$buff->data = array();

$buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count);

return $buff;

}

$start_count = ($page - 1) * $list_count;


$query = $this->getSelectPageSql($queryObject, $with_values, $start_count, $list_count);


$query .= (__DEBUG_QUERY__ & 1 && $queryObject->query_id) ? sprintf(' ' . $this->comment_syntax, $this->query_id) : '';

$result = $this->_query($query, $connection);

if($this->isError())

{

return $this->queryError($queryObject);

}


$virtual_no = $total_count - ($page - 1) * $list_count;

$data = $this->_fetch($result, $virtual_no);


$buff = new Object ();

$buff->total_count = $total_count;

$buff->total_page = $total_page;

$buff->page = $page;

$buff->data = $data;

$buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count);

return $buff;

}


/**

* If select query execute, return paging sql

* @param object $query

* @param boolean $with_values

* @param int $start_count

* @param int $list_count

* @return string select paging sql

*/

function getSelectPageSql($query, $with_values = true, $start_count = 0, $list_count = 0)

{

$select = $query->getSelectString($with_values);

if($select == '')

{

return new Object(-1, "Invalid query");

}

$select = 'SELECT ' . $select;


$from = $query->getFromString($with_values);

if($from == '')

{

return new Object(-1, "Invalid query");

}

$from = ' FROM ' . $from;


$where = $query->getWhereString($with_values);

if($where != '')

{

$where = ' WHERE ' . $where;

}


$groupBy = $query->getGroupByString();

if($groupBy != '')

{

$groupBy = ' GROUP BY ' . $groupBy;

}


$orderBy = $query->getOrderByString();

if($orderBy != '')

{

$orderBy = ' ORDER BY ' . $orderBy;

}


$limit = $query->getLimitString();

if($limit != '')

{

$limit = sprintf(' LIMIT %d, %d', $start_count, $list_count);

}


return $select . ' ' . $from . ' ' . $where . ' ' . $groupBy . ' ' . $orderBy . ' ' . $limit;

}


}


DBMysql::$isSupported = function_exists('mysql_connect');


/* End of file DBMysql.class.php */

/* Location: ./classes/db/DBMysql.class.php */




로그인 후 댓글쓰기가 가능합니다.

?

  1. PHP Opcache 적용 전과 후의 비교

  2. CSS, JS파일, gzip으로 한꺼번에 압축해서 전송하기

  3. 윈도우 time_wait 없애기

  4. [Apache] mod_expires .htaccess을 수정하여 브라우저 캐싱하기

  5. 아파치 모듈 mod_deflate 압축하기

  6. 서버 최적화 시키기(APACHE, PHP, MYSQL, XE 압축&캐싱&버퍼)

  7. APACHE PHP 에러 잡기

  8. 아파치 캐시 설정 이후 잦은 아파치 자동멈춤 현상 원인분석

  9. MySQL 5.6 my.cnf 글로벌 변수인지 세션변수인지 확인

  10. [아파치 error.log] Fatal Error Unable to reattach to base address

  11. 아파치 httpd.conf 재시작 없이 설정 적용하기

  12. XCOPY로 중요파일 백업하기

  13. 윈도우 TCP 연결의 개수를 최대한 늘이기

  14. XE 어느날 갑자기 다운로드가 되지 않을때 해결방법

  15. XE 스케치북 모바일 비회원 댓글쓰기에서 홈페이지 이메일 기입란 삭제하기

  16. ECS P43T-AD3, Asus C381GM, Driver(두번째 사용했던 서버 드라이버)

  17. XE 리퍼러 모듈로 트래픽 발생에 대처방법

  18. XE <title>제목 - 사이트명</title> 으로 변경방법

  19. XE Content font-size:수정방법

  20. 서버 부하상태 체크

Board Pagination Prev 1 2 3 4 5 Next
/ 5

http://urin79.com

우린친구블로그

sketchbook5, 스케치북5

sketchbook5, 스케치북5

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소