Index: trunk/src/game/Guild.cpp
===================================================================
--- trunk/src/game/Guild.cpp (revision 44)
+++ trunk/src/game/Guild.cpp (revision 88)
@@ -364,4 +364,19 @@
     else
     {
+		PCachePlayerInfo pInfo = objmgr.GetPlayerInfoFromCache(GUID_LOPART(guid));
+        if(pInfo)
+        {
+            plName = pInfo->sPlayerName;
+            plClass = pInfo->unClass;
+            if(plClass<CLASS_WARRIOR||plClass>=MAX_CLASSES)     // can be at broken `class` field
+            {
+                sLog.outError("Player (GUID: %u) has a broken data in field `characters`.`class`.",GUID_LOPART(guid));
+                return false;
+            }
+            plLevel = pInfo->unLevel;
+            plZone = Player::GetZoneIdFromDB(guid);
+        }
+        else
+        {
         if(!objmgr.GetPlayerNameByGUID(guid, plName))       // player doesn't exist
             return false;
@@ -387,4 +402,5 @@
         delete result;
     }
+	}
 
     memslot->name = plName;
Index: trunk/src/game/ObjectMgr.h
===================================================================
--- trunk/src/game/ObjectMgr.h (revision 85)
+++ trunk/src/game/ObjectMgr.h (revision 88)
@@ -210,4 +210,21 @@
 #define MAX_CONDITION                 11                    // maximum value in ConditionType enum
 
+//Player's info
+typedef struct _tagCachePlayerInfo
+{
+    std::string sPlayerName;
+    uint32 unfield;
+    uint32 unLevel;
+    uint8 unClass;
+//Arena
+    uint32 unArenaInfoId0;
+    uint32 unArenaInfoId1;
+    uint32 unArenaInfoId2;
+    uint32 unArenaInfoSlot0;
+    uint32 unArenaInfoSlot1;
+    uint32 unArenaInfoSlot2;
+}CachePlayerInfo, *PCachePlayerInfo;
+typedef HM_NAMESPACE::hash_map<uint32, PCachePlayerInfo> CachePlayerInfoMap;
+
 struct PlayerCondition
 {
@@ -569,4 +586,8 @@
         uint32 GenerateItemTextID();
         uint32 GeneratePetNumber();
+        
+        void LoadPlayerInfoInCache();
+        PCachePlayerInfo GetPlayerInfoFromCache(uint32 unPlayerGuid) const;
+        CachePlayerInfoMap m_mPlayerInfoMap;
 
         uint32 CreateItemText(std::string text);
Index: trunk/src/game/World.cpp
===================================================================
--- trunk/src/game/World.cpp (revision 85)
+++ trunk/src/game/World.cpp (revision 88)
@@ -989,4 +989,7 @@
     objmgr.LoadPageTexts();
 
+    sLog.outString( "Loading Player info in cache..." );
+    objmgr.LoadPlayerInfoInCache();
+
     sLog.outString( "Loading Game Object Templates..." );   // must be after LoadPageTexts
     objmgr.LoadGameobjectInfo();
Index: trunk/src/game/Player.cpp
===================================================================
--- trunk/src/game/Player.cpp (revision 78)
+++ trunk/src/game/Player.cpp (revision 88)
@@ -13627,4 +13627,38 @@
 uint32 Player::GetUInt32ValueFromDB(uint16 index, uint64 guid)
 {
+    //rognar optimization
+    //must be improved!! "if" and "switch" - it's very not aesthetically :)))
+    //but we should know whith data is cached
+    //PLAYER_FIELD_ARENA_TEAM_INFO* very is often using with pvp&arena patch :)
+    if(       index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5
+        || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5
+        || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5
+        || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6)
+        || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6)
+        || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)
+        || index == UNIT_FIELD_LEVEL)
+    {
+        CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GUID_LOPART(guid));
+        if(_iter != objmgr.m_mPlayerInfoMap.end())
+        {
+            switch(index)
+            {
+            case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5):
+                return _iter->second->unArenaInfoSlot0;
+            case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5):
+                return _iter->second->unArenaInfoSlot1;
+            case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5):
+                return _iter->second->unArenaInfoSlot2;
+            case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6)):
+                return _iter->second->unArenaInfoId0;
+            case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6)):
+                return _iter->second->unArenaInfoId1;
+            case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)):
+                return _iter->second->unArenaInfoId2;
+            case (UNIT_FIELD_LEVEL):
+                return _iter->second->unLevel;
+            }
+        }
+    }
     Tokens data;
     if(!LoadValuesArrayFromDB(data,guid))
@@ -15220,4 +15254,21 @@
     if(Pet* pet = GetPet())
         pet->SavePetToDB(PET_SAVE_AS_CURRENT);
+        
+    //to prevent access to DB we should cache some data, which is used very often
+    CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow());
+    if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players
+    {
+        _iter->second->unLevel = getLevel();
+
+        _iter->second->unArenaInfoSlot0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5);
+        _iter->second->unArenaInfoSlot1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5);
+        _iter->second->unArenaInfoSlot2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5);
+
+        _iter->second->unfield = GetUInt32Value(UNIT_FIELD_BYTES_0);
+
+        _iter->second->unArenaInfoId0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6));
+        _iter->second->unArenaInfoId1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6));
+        _iter->second->unArenaInfoId2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6));
+    }
 }
 
Index: trunk/src/game/ObjectMgr.cpp
===================================================================
--- trunk/src/game/ObjectMgr.cpp (revision 85)
+++ trunk/src/game/ObjectMgr.cpp (revision 88)
@@ -168,4 +168,7 @@
         delete (*itr);
 
+    for (CachePlayerInfoMap::iterator itr = m_mPlayerInfoMap.begin(); itr != m_mPlayerInfoMap.end(); ++itr)
+        delete itr->second;
+
     for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
         delete itr->second;
@@ -176,4 +179,59 @@
     for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
         itr->second.Clear();
+}
+
+void ObjectMgr::LoadPlayerInfoInCache()
+{
+    QueryResult *result = CharacterDatabase.PQuery("SELECT guid, name, data, class  FROM characters");
+    if(!result)
+    {
+        sLog.outError( "ROGNAR LoadPlayerCache");
+        return;
+    }
+
+    PCachePlayerInfo pPPlayerInfo = NULL;
+    Field *fields = NULL;
+    Tokens tdata;
+    barGoLink bar( result->GetRowCount() );
+    do
+    {
+        bar.step();
+        fields = result->Fetch();
+        pPPlayerInfo = new CachePlayerInfo();
+
+        pPPlayerInfo->sPlayerName = fields[1].GetString();
+
+        tdata.clear();
+        tdata = StrSplit(fields[2].GetCppString(), " ");
+        
+        pPPlayerInfo->unLevel = (uint32)atoi(tdata[UNIT_FIELD_LEVEL].c_str());
+        pPPlayerInfo->unfield = (uint32)atoi(tdata[UNIT_FIELD_BYTES_0].c_str());
+
+        pPPlayerInfo->unArenaInfoId0 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6)].c_str());
+        pPPlayerInfo->unArenaInfoId1 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6)].c_str());
+        pPPlayerInfo->unArenaInfoId2 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)].c_str());
+
+        pPPlayerInfo->unArenaInfoSlot0 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5].c_str());
+        pPPlayerInfo->unArenaInfoSlot1 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5].c_str());
+        pPPlayerInfo->unArenaInfoSlot2 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5].c_str());
+    
+        pPPlayerInfo->unClass = (uint32)fields[3].GetUInt32();
+        m_mPlayerInfoMap[fields[0].GetUInt32()] = pPPlayerInfo;
+    }
+    while (result->NextRow());
+    delete result;
+
+    sLog.outString();
+    sLog.outString( ">> Loaded info about %d players", m_mPlayerInfoMap.size());
+}
+
+PCachePlayerInfo ObjectMgr::GetPlayerInfoFromCache(uint32 unPlayerGuid) const
+{
+    //Now m_mPlayerInfoMap is using only for search, but when dinamic inserting/removing
+    //will be implemented we should lock it to prevent simultaneous access.
+    //Inserting - when new created player is saving
+    //Removing - when player has been deleted
+    CachePlayerInfoMap::const_iterator ipos = m_mPlayerInfoMap.find(unPlayerGuid);
+    return ipos == m_mPlayerInfoMap.end() ? NULL : ipos->second;
 }
 
@@ -1259,4 +1317,11 @@
     {
         name = player->GetName();
+        return true;
+    }
+
+    PCachePlayerInfo pInfo = GetPlayerInfoFromCache(GUID_LOPART(guid));
+    if(pInfo)
+    {
+        name = pInfo->sPlayerName.c_str();
         return true;
     }
